并排ListView——仿京东分类列表

文章出自 :http://blog.csdn.net/qibin0506/article/details/41776165

无意间看到京东的分类列表做的非常炫, 是那种横排列表的形式,本来是想截图上来的,但是公司没找到数据线。。。。好吧,今天我们也来实现个这种效果。 这次我选择的ListView,但是ListView默认是横向铺满屏的,怎么做到并排呢? 重写!!!

虽然京东的没法截图了,但是我自己做的效果可以在模拟器上运行,先来看看效果吧,界面有点丑,没关系,对吧? 我们主要研究的是如何实现这种框架,而不是界面本身。



恩, 界面确实有点丑,算了,还是直接看实现过程吧。

上面说了,这次我们选重写ListView, 那么我们的需求是什么呢? 很简单,重写它默认横向铺满屏的特性,让它可以wrap_content。

[java]  view plain copy
  1. public class MyListView extends ListView {  
  2.     public MyListView(Context context, AttributeSet attrs) {  
  3.         this(context, attrs, 0);  
  4.     }  
  5.   
  6.   
  7.     public MyListView(Context context, AttributeSet attrs, int defStyle) {  
  8.         super(context, attrs, defStyle);  
  9.     }  
  10.       
  11.     @Override  
  12.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  13.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  14.         int height = getMeasuredHeight();  
  15.         int width = 0;  
  16.           
  17.         int widthMode = MeasureSpec.getMode(widthMeasureSpec);  
  18.         int widthSize = MeasureSpec.getSize(widthMeasureSpec);  
  19.         if(widthMode == MeasureSpec.EXACTLY) {  
  20.             width = widthSize;  
  21.         }else {  
  22.             if(widthMode == MeasureSpec.AT_MOST) {  
  23.                 final int childCount = getChildCount();  
  24.                 for(int i=0;i<childCount;i++) {  
  25.                     View view = getChildAt(i);  
  26.                     measureChild(view, widthMeasureSpec, heightMeasureSpec);  
  27.                     width = Math.max(width, view.getMeasuredWidth());  
  28.                 }  
  29.             }  
  30.         }  
  31.           
  32.         setMeasuredDimension(width, height);  
  33.     }  
  34. }  


还是很简单的, 只重写了onMeasure()方法, 看看具体的逻辑吧。

13行,首先调用了super.onMeasure()方法,因为这里我们不考虑height,所以让ListView自己去算吧,我们只关心width/

14行,获取了ListView自己测量的结果,我们只需要height,因为width是我们自己需要计算的。

17~18行,不说了,获取父布局给推荐的mode和size。

接下来是一个if...else..., 在我们这个需求里,这个if...else...是多余的,但为了代码规范,还是加上了,有总比没有强吧。

if里,if的条件是widthMode == MeasureSpec.EXACTLY 即为精确值时, 这时候就不需要我们自己去计算了,直接赋值width为父布局给推荐的大小就ok。

看else里,这里又一个if,这个条件widthMode == MeasureSpec.AT_MOST 即当mode为尽量大时,也就是layout_width="wrap_content",好,这里需要我们自己做工作了。

23行,我们获取了所有的子item的个数。

接着24行一个for循环,获取所有的子view。

26行,通过measureChild(view, widthMeasureSpec, heightMeasureSpec);去测量一下该view的宽高。

27行,用width保存所有子view中宽度最大的那个的宽度。

最后的最后,32行,别忘了保存一下测量结果。


ok,重写的ListView搞定了,现在它就有了wrap_content的能力,赶紧来布局中布局它吧。

[html]  view plain copy
  1. <RelativeLayout 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.     tools:context=".MainActivity" >  
  6.   
  7.     <LinearLayout  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="wrap_content"  
  10.         android:orientation="horizontal"  
  11.         android:weightSum="3" >  
  12.   
  13.         <org.loader.jdmemu.MyListView  
  14.             android:id="@+id/list1"  
  15.             android:layout_width="0dip"  
  16.             android:layout_weight="1"  
  17.             android:layout_height="wrap_content"  
  18.             android:gravity="center"  
  19.             android:background="@android:color/darker_gray" />  
  20.         <org.loader.jdmemu.MyListView  
  21.             android:id="@+id/list2"  
  22.             android:layout_width="0dip"  
  23.             android:layout_weight="2"  
  24.             android:layout_height="wrap_content" />  
  25.     </LinearLayout>  
  26.   
  27. </RelativeLayout>  

可以看到,这里是两个并排的ListView,占的宽度比为1:2。前期工作都做完了,去Activity中填充数据看看效果吧。

[java]  view plain copy
  1. public class MainActivity extends Activity {  
  2.     private static final String[] mMenus = { "常用分类""服饰内衣""鞋靴""手机",  
  3.             "家用电器""数码""电脑办公""个护化妆""图书" };  
  4.   
  5.     private MyListView mListView1;  
  6.     private MyListView mListView2;  
  7.   
  8.     @Override  
  9.     protected void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         setContentView(R.layout.activity_main);  
  12.   
  13.         mListView1 = (MyListView) findViewById(R.id.list1);  
  14.         mListView2 = (MyListView) findViewById(R.id.list2);  
  15.           
  16.         mListView1.setAdapter(new ArrayAdapter<String>(this,  
  17.                 R.layout.menu, mMenus));  
  18.   
  19.         mListView1.setOnItemClickListener(new ItemClick());  
  20.     }  
  21.       
  22.     private class ItemClick implements OnItemClickListener {  
  23.         @Override  
  24.         public void onItemClick(AdapterView<?> parent, View view, int position,  
  25.                 long id) {  
  26.             mListView1.smoothScrollToPositionFromTop(position, 0);  
  27.             String[] items = new String[(position + 1) * 2];  
  28.             for(int i=0;i<items.length;i++) {  
  29.                 items[i] = mMenus[position] + "中的数据:" + i;  
  30.             }  
  31.             mListView2.setAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, items));  
  32.         }  
  33.     }  
  34. }  



恩,偷懒了,不过很好理解,就是为ListView1设置一个adapter,并通过ListView的itemClick动态改变ListView2的adapter。

重点看看

[java]  view plain copy
  1. mListView1.smoothScrollToPositionFromTop(position, 0);  

这句话的作用就是实现当我们点击该item时,让该ListView滑动,并到在该item到达顶部时停止,实现动画中那个自动滑动的ListView的效果。

如此简单,就可以达到文章刚开始的效果。

等等,突然想到,是不是可以把菜单做成侧滑的效果呢? 嘿嘿,应该还没有人这么干吧。 看来下篇文章可能就是“不一样的侧滑菜单了”。嘿嘿,今天下班回去研究研究。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值