热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

先上效果图:实现思路:1.先说右边标题:首先,右边的数据源集合中的Javabean中含有三个属性name,type,title,而每个条目中会默认含有一个标题.如果这是第一个条目,

先上效果图:

实现思路:

1.先说右边标题:

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

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

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

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

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

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

2.再说左边的Listview

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

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

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

第三  改变主标题的内容


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

一.写布局

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

 

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

 

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


2.左边Listview的Item布局文件

 

 1       
 2      3         android:layout_  
 4         android:layout_  
 5         android:background="#f9f9f9"  
 6         android:gravity="center"  
 7         android:orientation="vertical" >  
 8       
 9         <TextView  
10             android:id="@+id/tv_left"  
11             android:layout_  
12             android:layout_  
13             android:text="左边条目"  
14             android:textColor="#000000"  
15             android:textSize="18sp" />  
16       
17       
18       
19     3.右边Listview的Item布局文件  
20       
21       
22     23         android:layout_  
24         android:layout_  
25         android:background="#f9f9f9"  
26         android:gravity="center"  
27         android:orientation="vertical" >  
28       
29         <TextView  
30             android:id="@+id/tv_right"  
31             android:layout_  
32             android:layout_  
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_  
42             android:layout_  
43             android:gravity="center_vertical"  
44             android:orientation="horizontal" >  
45       
46             <ImageView  
47                 android:layout_  
48                 android:layout_  
49                 android:background="@drawable/jipai" />  
50       
51             <TextView  
52                 android:id="@+id/tv_content"  
53                 android:layout_  
54                 android:layout_  
55                 android:layout_marginLeft="50dp"  
56                 android:text="左边条目"  
57                 android:textColor="#000000"  
58                 android:textSize="18sp" />  
59           
60       
61       

 

二.创建Javabean

 

 1     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     }  

 

三.创建两个adapter

1.左边Listview的adapter

 

 1     /** 
 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     }  

 

2.右边Listview的adapter

 

 1     /** 
 2      * 右边listview的adapter 
 3      * 
 4      * @author HaiPeng 
 5      * 
 6      */  
 7     public class RightAdapter extends BaseAdapter {  
 8         private Context context;  
 9         private ArrayList data = new ArrayList();  
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 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     }  

 

四.MainActivity中操作

1.初始化数据

 

 1     private void initData() {  
 2             lists = new ArrayList();  
 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 ) {  
12                 lists.add(new BaseData(name1[i] + 1, i, title[0]));  
13             }  
14             for (int i = 0; i ) {  
15                 lists.add(new BaseData(name2[i] + 1, i, title[1]));  
16             }  
17             for (int i = 0; i ) {  
18                 lists.add(new BaseData(name3[i] + 1, i, title[2]));  
19             }  
20             for (int i = 0; i ) {  
21                 lists.add(new BaseData(name1[i] + 2, i, title[3]));  
22             }  
23             for (int i = 0; i ) {  
24                 lists.add(new BaseData(name2[i] + 2, i, title[4]));  
25             }  
26             for (int i = 0; i ) {  
27                 lists.add(new BaseData(name3[i] + 2, i, title[5]));  
28             }  
29             for (int i = 0; i ) {  
30                 lists.add(new BaseData(name1[i] + 3, i, title[6]));  
31             }  
32             for (int i = 0; i ) {  
33                 lists.add(new BaseData(name2[i] + 3, i, title[7]));  
34             }  
35             for (int i = 0; i ) {  
36                 lists.add(new BaseData(name3[i] + 3, i, title[8]));  
37             }  
38       
39     //假数据创建的方式比较low,大家不喜勿喷  
40       
41     //看下边这个集合,这个集合是右边所有要显示标题的条目的position  
42       
43           ArrayList  showTitle = new ArrayList();  
44             for (int i = 0; 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     //这个集合也就是就是左边和右边类型联系的桥梁  

 

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

 

 1  @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());// 主标题栏设置默认初始值

 

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

 

 1     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             });  

 

4.左边Listview的点击事件

 

 1     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             });  

 

5.updateLeftListview方法

 

 1    /** 
 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     } 

 

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

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

 

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

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

 

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

 


推荐阅读
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文讲述了如何通过代码在Android中更改Recycler视图项的背景颜色。通过在onBindViewHolder方法中设置条件判断,可以实现根据条件改变背景颜色的效果。同时,还介绍了如何修改底部边框颜色以及提供了RecyclerView Fragment layout.xml和项目布局文件的示例代码。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 本文介绍了在Linux下安装Perl的步骤,并提供了一个简单的Perl程序示例。同时,还展示了运行该程序的结果。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 在开发app时,使用了butterknife后,在androidStudio打包apk时可能会遇到报错。为了解决这个问题,可以通过打开proguard-rules.pro文件进行代码混淆来解决。本文介绍了具体的混淆代码和方法。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
author-avatar
爱你不愿放cwy
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有