Android Imitation eleme Point Menu Page Two-level linkage list _android

Source: Internet
Author: User
Tags touch

This weekend, a lot of selling points, just like a copy of "Hungry" good. First of all, this order page is not very familiar:

The ListView on the right, after the group, is indexed on the Left tab page. Can direct navigation, is not very convenient. The key is to slide to the right, the left will also follow the slide, and click on the left, can also locate the right item. They have such a special interaction. Similar to the effect of this linkage, there are some common examples, such as knowing that the use of common toolbar+viewpager linkage, but is up and down layout:

Then look at the comments, its City selection page also has this linkage shadow, just a little weaker. The sidebar can index the ListView, which is the first in the micro-trust buddy list:

I'll have one on the weekends. As far as expansion is concerned, it should be fit for all of the above. I call it linkedlayout, look at the effect chart:

I put the right in 5 groups, you can see, the left index = right/5

Characteristics

Slide right, move left.

Slide to the left, move to the right.

Click on the left tab, slide right to the corresponding group

Source

GitHub Transmission door: Https://github.com/fashare2015/LinkedScrollDemo

Knowledge points

Before you do, list the knowledge points, or what we can harvest from this demo.

Abstract/Interface Programming oriented

customizing view

Agent mode

UML Class Diagram

Review the details of ListView && Recyclerview

Feeling finished after the biggest harvest or 1th, interface-oriented programming. In fact, the completion of the function of only half the time, behind the time has been in the abstract and reconstruction; Hey, one-step is too difficult, or honest to write specific classes, and then extract the base class.

Idea

UI section

Linkedlayout

What to do is two interrelated lists, on the left as tab, and on the right as the content page. Regardless of the interaction, let's make an interface: Engage a class called Linkedlayout to hold the tab and content:

public class Linkedlayout extends LinearLayout {
  private context mcontext;
  Private Basescrollablecontainer Mtabcontainer;
  Private Basescrollablecontainer Mcontentcontainer;
  Private Sectionindexer msectionindexer; Agent
  ...
}

We let it inherit the LinearLayout, and hold two container, and a God object Mcontext, and a group sectionindexer.

Basescrollablecontainer

Forget these first, mainly look at two container, from the name of a tab page, one is the content page, hehe. Because they can all be scroll, just get a basescrollablecontainer. The name is container, of course, salute fragment. Let's define this class:
Preliminary thought, nothing but a mcontext, a viewgroup, there are some Listener:

Public abstract class Basescrollablecontainer<vg extends Viewgroup> {
  protected context Mcontext;
  Public VG Mviewgroup;
  protected Realonscrolllistener Mrealonscrolllistener;
  Private Eventdispatcher Meventdispatcher;
  ...
}

As we expected, Mcontext context, Mviewgroup basically refers to our two ListView. Of course, after I want to do toolbar+viewpager, must rely on abstraction, can not directly write ListView. The remaining two are listener, when we have the interface set up, write the interaction of the time in the look.

It seems that UML diagrams are still good, and that inheritance and dependency relationships are at a glance.

Customizing view && Dynamic Layout

All right, here's the custom view link. We've got a linkedlayout, this is our Activity_main.xml layout code:

<?xml version= "1.0" encoding= "Utf-8"?> <relativelayout xmlns:android=
  "http://" Schemas.android.com/apk/res/android "
  xmlns:tools=" Http://schemas.android.com/tools "
  android:layout_ Width= "Match_parent"
  android:layout_height= "match_parent" >

  < Com.fashare.linkedscrolldemo.ui.LinkedLayout
    android:id= "@+id/linked_layout"
    android:layout_width= " Match_parent "
    android:layout_height=" match_parent "
    android:orientation=" horizontal "/>
</ Relativelayout>

Wipe it, it's gone? The rest depends on the Java code. Back to Linkedlayout, let's lay ui~:

public class Linkedlayout extends LinearLayout {... private static final int measure_by_weight = 0;
  Private static final float Weight_tab = 1;

  Private static final float weight_content = 3; public void Setcontainers (Basescrollablecontainer tabcontainer, Basescrollablecontainer contentcontainer) {MTabConta
    Iner = Tabcontainer;
    Mcontentcontainer = Contentcontainer;
    Mtabcontainer.seteventdispatcher (this);

    Mcontentcontainer.seteventdispatcher (this);
        Set Layoutparams MTabContainer.mViewGroup.setLayoutParams (The new Linearlayout.layoutparams (Measure_by_weight,

    ViewGroup.LayoutParams.WRAP_CONTENT, Weight_tab)); MContentContainer.mViewGroup.setLayoutParams (New Linearlayout.layoutparams (Measure_by_weight, VIEWGROUP.L

    Ayoutparams.match_parent, weight_content));
    This.addview (Mtabcontainer.mviewgroup);
    This.addview (Mcontentcontainer.mviewgroup);
  This.setorientation (horizontal); }
}

Got a setcontainers to inject our container, there are some like layout_height,layout_width,layout_weight,orientation, very familiar with it, and XML is not bad. Incidentally, we use the Weight property to control this ratio of 1:3, always feel this property is more magical ...

Inject ViewGroup, use custom linkedlayout

So far, the linkedlayout has been laid out, and we can use the ViewGroup separately. Here I use ListView as Tab,recyclerview for content. Imagination is limited, used to seem to have so many controls ... This part of the code is very simple, in the mainactivity, it is not posted.

Sub-class Basescrollablecontainer

According to common sense, the bottom should implement the base class. In the previous mainactivity, we are instantiated like this:

Mtabcontainer = new Listviewtabcontainer (this, mlistview); 
Mcontentcontainer = new Recyclerviewcontentcontainer (this, mrecyclerview);

Look at the name. One is ListView-padded tab and one is the content of the Recyclerview fill. First implement these two classes, as you can see from the diagram, they inherit from the Basescrollablecontainer, and are held by Linkedlayout:

Interactive section

Interaction with the User: Onscrolllistener and proxy mode

Finally to the interactive part, since it is sliding, there is no definition of the listener. However, the trouble is that ListView and Recyclerview respective Onscrolllistener are not the same, this time if their respective implementation, both troublesome and redundant. Like this:

Recyclerview public class Recyclerviewcontentcontainer extends Basescrollablecontainer<recyclerview> {... @
  Override protected void Setonscrolllistener () {Mviewgroup.addonscrolllistener (New Proxyonscrolllistener ()); Private class Proxyonscrolllistener extends Recyclerview.onscrolllistener {@Override public void Onscrollsta
        Techanged (Recyclerview recyclerview, int newstate) {if (newstate = = Recyclerview.scroll_state_idle) {//Stop sliding 1. Stop logic ...}
    else if (newstate = = recyclerview.scroll_state_dragging) {//press drag 2. The logic when you just drag ...}
  @Override public void onscrolled (recyclerview recyclerview, int dx, int dy) {//sliding 3. Sliding logic ...} }//ListView public class Listviewtabcontainer extends basescrollablecontainer<listview> {... @Override p
    rotected void Setonscrolllistener () {Mviewgroup.setonscrolllistener (New Proxyonscrolllistener ());

  ...
  } public class ProxyonscrolllistEner implements abslistview.onscrolllistener{@Override public void onscrollstatechanged (abslistview view, int scr Ollstate) {if (scrollstate = = Scroll_state_idle) {//Stop sliding 1. Logic at Stop ...}

    else if (scrollstate = = scroll_state_touch_scroll)//Press drag 2. Just drag when the logic ...}
      @Override public void Onscroll (Abslistview view, int firstvisibleitem, int visibleitemcount, int totalitemcount) { 3. Sliding logic ...//Sliding}}}

So what to do, although the differences between their onscrolllistener is very large, but careful observation can be found that many of the logic is similar, can be shared. In this case, you can use proxy mode to do refactoring. I extracted 1, 2, 3 of the logic, because in the abstract sense is consistent, can be organized into interfaces:

Public interface Onscrolllistener {
  //tab-click event
  void OnClick (int position);

  1. Sliding start
  void Onscrollstart ();

  2. Sliding end
  void Onscrollstop ();

  3. Trigger onscrolled ()
  void onscrolled ();

  The user manually slides, triggering the onscrolled ()
  void Onscrolledbyuser ();

  The program calls Scrollto (), triggering the onscrolled ()
  void onscrolledbyinvoked ();
}

At the same time, Recyclerview and listview their respective listeners as a proxy class, the 1, 2, 3 of the logic are entrusted to a certain tray-man, do not have to do their own to achieve, pour also fell relaxed at ease. As shown here: Write a picture description here

And then, let's take a look at this realonscrolllistener: ...

Is worthy of an honest class, it honestly took the Onscrolllistener all the interface, and was two proxy class proxies ... Held (not shown in the picture. )。
Concrete implementation will not be pasted, we can look at the source code. Here's a rough analysis, it has three members:

public class Realonscrolllistener implements Onscrolllistener {public
  Boolean istouching = false;//In Touch State
  Priv ate int mcurposition = 0;    Currently selected
  private baseviewgrouputil<vg> mviewutil//ViewGroup tool class
  ...
}

Istouching:

Why do you want to maintain this touch state? This is because our effect is linkage. This is more annoying, when onscrolled () is called, we can not tell whether the user's sliding, or from another list of the linkage effect of sliding. So let's record the istouching state, and we can separate the two situations.
The logic of the change istouching is in Onscrollstart () and Onscrollstop ().

Mcurposition:

This is a good explanation for each slide we need to record the current position, and then notify another list for linkage.
This logic is in onscrolled ().

Mviewutil:
A tool library for simplifying logic. There are probably Scrollto (), setviewselected (), updateposonscrolled () and other methods, as shown in the figure:

The interaction between two container

Before is the user's interaction, finally to the linkage part. Not in a hurry to realize, first answer me a question: Suppose I have two fragment in an activity, ask them how to communicate?

A classmate loudly way: with the radio
Classmate B: Eventbus!!!
C Classmate: See my Rxbus ...
Don't make a fuss, okay? Give me an honest listener. Obviously, we are facing the same scene here. Linkedlayout=activity,container=fragment.
Before you start, define listener, and take the first two-point name:


 * * Event distributor
 /Public
interface Eventdispatcher {
  /**
   * Distribution event: Pos selected in Fromview
   * @param pos
   
    * @param fromview
   *
  /void dispatchitemselectedevent (int pos, View fromview);
}
 * * Event recipient
 /Public
interface Eventreceiver {
  /**
   * Received event: immediately select Newpos
   * @param newpos< c18/>*/
  void SelectItem (int newpos);
}
   

Then linkedlayout as the parent element, which is definitely the role of the Distributor, should implement Eventdispatcher, and Basescrollablecontainer as a child element that accepts the event and should implement Eventreceiver. Look at the class diagram:

Look at the corresponding implementation (Eventreceiver):

Public abstract class BASESCROLLABLECONTAINER&LT;VG extends viewgroup> implements Eventreceiver {protected real
  Onscrolllistener Mrealonscrolllistener; Private Eventdispatcher Meventdispatcher; 
  Hold distributor ... public void Seteventdispatcher (Eventdispatcher eventdispatcher) {meventdispatcher = Eventdispatcher; }///meventdispatcher, i.e. linkedlayout protected void dispatchitemselectedevent (int curposition) {if (meventd
  Ispatcher!= null) meventdispatcher.dispatchitemselectedevent (curposition, Mviewgroup);
  @Override public void SelectItem (int newpos) {mrealonscrolllistener.selectitem (newpos); }//Onscrolllistener: Proxy mode public class Realonscrolllistener implements Onscrolllistener {... public void SE
      Lectitem (int position) {mcurposition = position;
      LOG.D ("SetItem", Position + "");
Linkage events from the other side mviewutil.smoothscrollto (position);
      if (Mviewutil.isvisiblepos (position))//Cursection is visible, does not scroll  mviewutil.setviewselected (position);
      @Override public void OnClick (int position) {istouching = true;
      mviewutil.setviewselected (mcurposition = position); Dispatchitemselectedevent (position);
    Click tab to distribute Event istouching = false;
      @Override public void onscrolled () {mcurposition = mviewutil.updateposonscrolled (mcurposition);
      if (istouching)//From the user, notify the other side linkage onscrolledbyuser ();
    else//From the other side, passive sliding does not respond to onscrolledbyinvoked ();  @Override public void Onscrolledbyuser () {dispatchitemselectedevent (mcurposition); From the user, notify the other Side linkage}}}

Look Again (Eventdispatcher):

public class Linkedlayout extends LinearLayout implements Eventdispatcher {
  private Basescrollablecontainer Mtabcontainer;
  Private Basescrollablecontainer Mcontentcontainer;
  Private Sectionindexer msectionindexer; Group Interface
  ...
  @Override public
  void dispatchitemselectedevent (int pos, View fromview) {
    if (Fromview = = Mcontentcontainer.mviewgroup) {//from content, forwarded to tab
      int convertpos = msectionindexer.getsectionforposition (POS);
      Mtabcontainer.selectitem (Convertpos);
    } else {          //From tab, forwarded to content
      int convertpos = msectionindexer.getpositionforsection (POS);
      Mcontentcontainer.selectitem (Convertpos);}}

Summarize

So far, is there a kind of hearty feeling? In any case, object-oriented is a belief, the definition of a good interface, how to write how comfortable.
TODO: Before that, this linkage is generic. Then there will be time to continue to achieve a toolbar+viewpager linkage ...

Eggs

HD Uncensored Class Diagram: (complete)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.