• 仿美团外卖,饿了吗 两个ListView联动,左边点击切换右边,右边滑动切换左边


    先上效果图:

    实现思路:

    1.先说右边标题:

    首先,右边的数据源集合中的Javabean中含有三个属性name,type,title,而每个条目中会默认含有一个标题.

    如果这是第一个条目,就让标题显示出来,再如果这个条目的类型和上一个条目的类型不一样,就让这个条目的标题显示出来,否则,就隐藏标题,  这样我们就做到了每种类型只有第一个数据标题显示出来

    接着,在Listview的外层(也就是MainActivity的布局文件中),默认放一个标题(下面都称作是主标题)

    最后,设置右边Listview的滚动监听事件    在onScroll方法中,我们要做两件事:

         第一件事是每当前第一个可见条目的类型和当前左边Listview选择的类型(红色字体的类型) 不一样时,需要将主标题的内容改变

         第二件事  同时切换左边Listview的选中状态

    2.再说左边的Listview

    左边的Listview需要设置条目点击事件,在点击事件中需要干三件事:

    第一  将左边点击条目的字体颜色改变

    第二   将右边Listview滚动至左边Listview所选择类型相同的区域

    第三  改变主标题的内容


    说到这,大家可能还是云里雾里的,还是不知道左边的类型和右边的类型是怎么关联起来的?没关系,在下面的代码解析中你就会明白!下边是具体的实现步骤:

    一.写布局

    1.在MainActivity的布局文件中    添加应有的控件

     1 <span style="font-size:14px;"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
     2     xmlns:tools="http://schemas.android.com/tools"  
     3     android:layout_width="match_parent"  
     4     android:layout_height="match_parent"  
     5     android:orientation="horizontal"  
     6     tools:context=".MainActivity" >  
     7   
     8     <ListView  
     9         android:id="@+id/lv_left"  
    10         android:layout_width="0dp"  
    11         android:layout_height="match_parent"  
    12         android:layout_weight="1" >  
    13     </ListView>  
    14   
    15     <RelativeLayout  
    16         android:layout_width="0dp"  
    17         android:layout_height="match_parent"  
    18         android:layout_weight="3" >  
    19   
    20         <ListView  
    21             android:id="@+id/lv_Right"  
    22             android:layout_width="match_parent"  
    23             android:layout_height="match_parent" >  
    24         </ListView>  
    25   
    26         <TextView  
    27             android:id="@+id/tv_title"  
    28             android:layout_width="match_parent"  
    29             android:layout_height="wrap_content"  
    30             android:background="#9f9f9f"  
    31             android:gravity="center"  
    32             android:padding="5dp"  
    33             android:textColor="#000000"  
    34             android:textSize="18sp" />  
    35     </RelativeLayout>  
    36   
    37 </LinearLayout></span> 

    注意   这里边将Listview和主标题textView放在一个相对布局中,并且先放Listview,后放textView,目的是将主标题放在Listview的空间的上方


    2.左边Listview的Item布局文件

     1     <span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>  
     2     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
     3         android:layout_width="match_parent"  
     4         android:layout_height="50dp"  
     5         android:background="#f9f9f9"  
     6         android:gravity="center"  
     7         android:orientation="vertical" >  
     8       
     9         <TextView  
    10             android:id="@+id/tv_left"  
    11             android:layout_width="wrap_content"  
    12             android:layout_height="wrap_content"  
    13             android:text="左边条目"  
    14             android:textColor="#000000"  
    15             android:textSize="18sp" />  
    16       
    17     </LinearLayout></span>  
    18       
    19     <span style="font-size:18px;">3.右边Listview的Item布局文件</span>  
    20       
    21     <span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>  
    22     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    23         android:layout_width="match_parent"  
    24         android:layout_height="wrap_content"  
    25         android:background="#f9f9f9"  
    26         android:gravity="center"  
    27         android:orientation="vertical" >  
    28       
    29         <TextView  
    30             android:id="@+id/tv_right"  
    31             android:layout_width="match_parent"  
    32             android:layout_height="wrap_content"  
    33             android:background="#9f9f9f"  
    34             android:gravity="center"  
    35             android:padding="5dp"  
    36             android:text="右边条目"  
    37             android:textColor="#000000"  
    38             android:textSize="18sp" />  
    39       
    40         <LinearLayout  
    41             android:layout_width="match_parent"  
    42             android:layout_height="90dp"  
    43             android:gravity="center_vertical"  
    44             android:orientation="horizontal" >  
    45       
    46             <ImageView  
    47                 android:layout_width="80dp"  
    48                 android:layout_height="80dp"  
    49                 android:background="@drawable/jipai" />  
    50       
    51             <TextView  
    52                 android:id="@+id/tv_content"  
    53                 android:layout_width="wrap_content"  
    54                 android:layout_height="wrap_content"  
    55                 android:layout_marginLeft="50dp"  
    56                 android:text="左边条目"  
    57                 android:textColor="#000000"  
    58                 android:textSize="18sp" />  
    59         </LinearLayout>  
    60       
    61     </LinearLayout></span>  

    二.创建Javabean

     1     <span style="font-size:14px;">public class BaseData {  
     2         private String name;  
     3         private int type;// 类型 后边要根据类型显示标题  
     4         private String title;//  
     5       
     6         public BaseData(String name, int type, String title) {  
     7             super();  
     8             this.name = name;  
     9             this.type = type;  
    10             this.title = title;  
    11         }  
    12       
    13         public BaseData() {  
    14             super();  
    15         }  
    16       
    17         public String getTitle() {  
    18             return title;  
    19         }  
    20       
    21         public void setTitle(String title) {  
    22             this.title = title;  
    23         }  
    24       
    25         public String getName() {  
    26             return name;  
    27         }  
    28       
    29         public void setName(String name) {  
    30             this.name = name;  
    31         }  
    32       
    33         public int getType() {  
    34             return type;  
    35         }  
    36       
    37         public void setType(int type) {  
    38             this.type = type;  
    39         }  
    40       
    41     }</span>  

    三.创建两个adapter

    1.左边Listview的adapter

     1     <span style="font-size:14px;">/** 
     2      * 左边的adapter   注意要给textview设置tag 
     3      * @author HaiPeng 
     4      * 
     5      */  
     6     public class LeftAdapter extends BaseAdapter {  
     7       
     8         private Context context;  
     9         String data[]={"蔬菜1","水果1","姓氏1","蔬菜2","水果2","姓氏2","蔬菜3","水果3","姓氏3"};  
    10       
    11         public LeftAdapter(Context context) {  
    12             super();  
    13             this.context = context;  
    14         }  
    15       
    16         @Override  
    17         public int getCount() {  
    18             return data.length;  
    19         }  
    20       
    21         @Override  
    22         public Object getItem(int position) {  
    23             return null;  
    24         }  
    25       
    26         @Override  
    27         public long getItemId(int position) {  
    28             return 0;  
    29         }  
    30       
    31         @Override  
    32         public View getView(final int position, View convertView, ViewGroup parent) {  
    33             ViewHold vh = null;  
    34             if (convertView == null) {  
    35                 convertView = View.inflate(context, R.layout.item_left, null);  
    36                 vh = new ViewHold();  
    37                 convertView.setTag(vh);  
    38                 vh.tv_left = (TextView) convertView.findViewById(R.id.tv_left);  
    39             } else {  
    40                 vh = (ViewHold) convertView.getTag();  
    41             }  
    42             vh.tv_left.setTag(position);  
    43             vh.tv_left.setText(data[position]);  
    44             return convertView;  
    45         }  
    46       
    47         public class ViewHold {  
    48             TextView tv_left;  
    49               
    50         }  
    51     }</span>  

    2.右边Listview的adapter

     1     <span style="font-size:14px;">/** 
     2      * 右边listview的adapter 
     3      * 
     4      * @author HaiPeng 
     5      * 
     6      */  
     7     public class RightAdapter extends BaseAdapter {  
     8         private Context context;  
     9         private ArrayList<BaseData> data = new ArrayList<BaseData>();  
    10       
    11         public RightAdapter(Context context) {  
    12             super();  
    13             this.context = context;  
    14         }  
    15       
    16         /** 
    17          * 这个方法是用来更新数据源 
    18          * 
    19          * @param context 
    20          */  
    21       
    22         public void updateData(ArrayList<BaseData> lists) {  
    23             data.clear();  
    24             data.addAll(lists);  
    25             this.notifyDataSetChanged();  
    26         }  
    27       
    28         @Override  
    29         public int getCount() {  
    30             // TODO Auto-generated method stub  
    31             return data.size();  
    32         }  
    33       
    34         @Override  
    35         public Object getItem(int position) {  
    36       
    37             return null;  
    38         }  
    39       
    40         @Override  
    41         public long getItemId(int position) {  
    42             // TODO Auto-generated method stub  
    43             return 0;  
    44         }  
    45       
    46         @Override  
    47         public View getView(int position, View convertView, ViewGroup parent) {  
    48             ViewHold vh = null;  
    49             if (convertView == null) {  
    50                 convertView = View.inflate(context, R.layout.item_right, null);  
    51                 vh = new ViewHold();  
    52                 convertView.setTag(vh);  
    53                 vh.tv_content = (TextView) convertView  
    54                         .findViewById(R.id.tv_content);  
    55                 vh.tv_right = (TextView) convertView.findViewById(R.id.tv_right);  
    56             } else {  
    57                 vh = (ViewHold) convertView.getTag();  
    58             }  
    59             vh.tv_content.setText(data.get(position).getName());  
    60             if (position == 0) {//如果是第一个  需要显示标题  
    61                 vh.tv_right.setVisibility(View.VISIBLE);  
    62                 vh.tv_right.setText(data.get(position).getTitle());  
    63             } else if (!TextUtils.equals(data.get(position).getTitle(),  
    64                     data.get(position - 1).getTitle())) {//如果这个标题和上一个不一样   也需要将标题显示出来  
    65                 vh.tv_right.setVisibility(View.VISIBLE);  
    66                 vh.tv_right.setText(data.get(position).getTitle());  
    67             } else {  
    68                 vh.tv_right.setVisibility(View.GONE);  
    69             }  
    70             return convertView;  
    71         }  
    72       
    73         public class ViewHold {  
    74             TextView tv_content;  
    75             TextView tv_right;  
    76         }  
    77       
    78     }</span>  

    四.MainActivity中操作

    1.初始化数据

     1     <span style="font-size:14px;">private void initData() {  
     2             lists = new ArrayList<BaseData>();  
     3             String title[] = { "蔬菜1", "水果1", "姓氏1", "蔬菜2", "水果2", "姓氏2", "蔬菜3",  
     4                     "水果3", "姓氏3" };  
     5             String name1[] = { "萝卜", "大葱", "茄子", "大蒜", "生姜", "萝卜", "大葱", "茄子",  
     6                     "大蒜", "生姜", "萝卜", "大葱" };  
     7             String name2[] = { "苹果", "梨", "香蕉", "西瓜", "橘子", "大枣", "菠萝", "红提", "葡萄",  
     8                     "樱桃", "椰子" };  
     9             String name3[] = { "郑", "王", "伊", "荆", "汤", "王", "孙", "李", "钱", "赵",  
    10                     "祁", "韦", "宏" };  
    11             for (int i = 0; i < name1.length; i++) {  
    12                 lists.add(new BaseData(name1[i] + 1, i, title[0]));  
    13             }  
    14             for (int i = 0; i < name2.length; i++) {  
    15                 lists.add(new BaseData(name2[i] + 1, i, title[1]));  
    16             }  
    17             for (int i = 0; i < name3.length; i++) {  
    18                 lists.add(new BaseData(name3[i] + 1, i, title[2]));  
    19             }  
    20             for (int i = 0; i < name1.length; i++) {  
    21                 lists.add(new BaseData(name1[i] + 2, i, title[3]));  
    22             }  
    23             for (int i = 0; i < name2.length; i++) {  
    24                 lists.add(new BaseData(name2[i] + 2, i, title[4]));  
    25             }  
    26             for (int i = 0; i < name3.length; i++) {  
    27                 lists.add(new BaseData(name3[i] + 2, i, title[5]));  
    28             }  
    29             for (int i = 0; i < name1.length; i++) {  
    30                 lists.add(new BaseData(name1[i] + 3, i, title[6]));  
    31             }  
    32             for (int i = 0; i < name2.length; i++) {  
    33                 lists.add(new BaseData(name2[i] + 3, i, title[7]));  
    34             }  
    35             for (int i = 0; i < name3.length; i++) {  
    36                 lists.add(new BaseData(name3[i] + 3, i, title[8]));  
    37             }  
    38       
    39     //假数据创建的方式比较low,大家不喜勿喷  
    40       
    41     //看下边这个集合,这个集合是右边所有要显示标题的条目的position  
    42       
    43           ArrayList<String>  showTitle = new ArrayList<String>();  
    44             for (int i = 0; i < lists.size(); i++) {  
    45                 if (i == 0) {//第一个必须显示  
    46                     showTitle.add(i + "");  
    47                 } else if (!TextUtils.equals(lists.get(i).getTitle(),  
    48                         lists.get(i - 1).getTitle())) {//如果跟上一个条目的type不一样就必须显示  
    49                     showTitle.add(i + "");  
    50                 }  
    51             }  
    52         }  
    53       
    54     //这个集合也就是就是左边和右边类型联系的桥梁</span>  

    2.初始化布局,我用的xutils的注解

     1 <span style="font-size:14px;"> @ViewInject(R.id.lv_left)  
     2     private ListView lv_left;  
     3   
     4     @ViewInject(R.id.lv_Right)  
     5     private ListView lv_Right;  
     6   
     7     @ViewInject(R.id.tv_title)  
     8     private TextView tv_title;  
     9   
    10 //但不要忘记在onCreate方法ViewUtils.inject(this);  
    11   
    12         leftAdapter = new LeftAdapter(context);  
    13         lv_left.setAdapter(leftAdapter);  
    14   
    15         rightAdapter = new RightAdapter(context);  
    16         lv_Right.setAdapter(rightAdapter);  
    17         rightAdapter.updateData(lists);// 将数据源传递给Listview  
    18   
    19         tv_title.setText(lists.get(0).getTitle());// 主标题栏设置默认初始值</span>

    3.先看右边的Listview的滚动监听事件

     1     <span style="font-size:14px;">lv_Right.setOnScrollListener(new OnScrollListener() {  
     2       
     3                 @Override  
     4                 public void onScroll(AbsListView view, int firstVisibleItem,  
     5                         int visibleItemCount, int totalItemCount) {  
     6                     int currentPosition = showTitle.indexOf(firstVisibleItem + "");//当前选中的一级条目的position    
     7       
     8                                   //firstVisibleItem是右边Listview当前第一个可见条目的position   根据//showTitle.indexOf(firstVisibleItem + "")可以得到这个数字在showTitle集合中的排序(是第几个),而这个排序刚好就是  
     9       
    10     //左边Listview当前所选中的条目的position 这样我们就能根据左边的类型判断右边的类型了  
    11       
    12                 //  updateLeftListview(firstVisibleItem, currentPosition);//这个方法下面会说  是一个抽出来的方法   左边//Listview的点击事件也会用到  
    13       
    14                 }  
    15       
    16                 @Override  
    17                 public void onScrollStateChanged(AbsListView view, int scrollState) {  
    18                 }  
    19       
    20             });</span>  

    4.左边Listview的点击事件

     1     <span style="font-size:14px;">lv_left.setOnItemClickListener(new OnItemClickListener() {  
     2       
     3                 @Override  
     4                 public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,  
     5                         long arg3) {  
     6                     int firstVisibleItem = lv_Right.getFirstVisiblePosition();     
     7      //右边Listview当前第一个可见条目的position  
     8                     updateLeftListview(firstVisibleItem, arg2);   
     9                     lv_Right.setSelection(Integer.parseInt(showTitle.get(arg2)));   
    10     //arg2是点击(选择)左边条目的第几个     
    11     //根据这个数字我们就能通过Integer.parseInt(showTitle.get(arg2))得到在点击左边后应该跳转到右边第几个条目      
    12      //  通过etSelection方法跳转     
    13                 }  
    14             });</span>  

    5.updateLeftListview方法

     1 <span style="font-size:14px;">   /** 
     2      * 更新左边Listview字体颜色  并且更改主标题的内容 
     3      * 
     4      * @param firstVisibleItem 
     5      *            右边当前第一个可见的条目position 
     6      * @param currentPosition 
     7      *            左边listview当前被点击或者要显示为红色的条目position 
     8      */  
     9     private void updateLeftListview(int firstVisibleItem, int currentPosition) {  
    10         if (showTitle.contains(firstVisibleItem + "")) {//右边的Listview滑动到这firstVisibleItem这个条目时   
    11 // 而showTitle中包含firstVisibleItem  那么这个时候我们就需要将主标题的内容修改和firstVisibleItem的标题一样      
    12 // 并且左边Listview需要更改颜色的条目(点击需要更改或者右边滑动应该改变的textView)的字体颜色改变掉  
    13   
    14            tv_title.setText(lists.get(firstVisibleItem).getTitle());//将主标题的内容修改和firstVisibleItem的标题一样  
    15             TextView lasTextView = (TextView) lv_left  
    16                     .findViewWithTag(lastPosition);  
    17             if (lasTextView != null) {//在右边Listview第一次加载过程中会一直调用监听中的onscroll  这时的textView可能为空  
    18                 lasTextView.setTextColor(Color.BLACK);//先将上一个textView字体的颜色改成黑色  
    19             }  
    20             TextView currenTextView = (TextView) lv_left  
    21                     .findViewWithTag(currentPosition);  
    22             if (currenTextView != null) {//再将当前要改变的extView字体的颜色改成红色  
    23                 currenTextView.setTextColor(Color.RED);  
    24             }  
    25             lastPosition = currentPosition;  
    26   
    27         }  
    28     }</span> 

    到这大家应该大概明白左边点击切换右边,右边滑动切换左边是怎么实现的了吧

      这里是源码的下载地址http://download.csdn.net/detail/jeff169/9520261

    PS:要是使用网络解析的数据, 可以再加点代码;

          首先创建一个数组:
    private ArrayList<Object> data=new ArrayList<Object>();
    再添加一个更新数据源的代码:
    public void updateData(ArrayList<Object> data){
    this.data.clear();
    this.data.addAll(data);
    notifyDatasetChanged();
    }
    最后在需要更新数据的时候调适配器的updateData这个方法。

    注意里边的Object改成你解析的实体类!

  • 相关阅读:
    return, break, continue
    equals 与 ==
    过滤器
    通过域名区分虚拟主机
    通过端口区分不同虚拟机
    Nginx实现反向代理
    Nginx安装
    poj2387 Til the Cows Come Home(Dijkstra)
    hdoj2544 最短路(Dijkstra || Floyd || SPFA)
    最小生成树
  • 原文地址:https://www.cnblogs.com/huolongluo/p/5797776.html
Copyright © 2020-2023  润新知