首页 > 代码库 > 二级横向菜单实现——ListView

二级横向菜单实现——ListView

实现类似于大众点评客户端的横向listview二级列表

   这种横向的listview二级列表在手机软件上还不太常见,但是使用过平板的都应该知道,在平板上市比较常见的。可能是因为平板屏幕比较大,而且也能展现更多的内容。

    下面来看一下我的实现步骤。

    首先自定义一个listview,代码如下:

 

[html] view plaincopy
 
  1. public class MyListView extends ListView implements Runnable {  
  2.     private float mLastDownY = 0f;   
  3.     private int mDistance = 0;   
  4.     private int mStep = 10;   
  5.     private boolean mPositive = false;   
  6.    
  7.   
  8.     public MyListView (Context context, AttributeSet attrs) {   
  9.           super(context, attrs);   
  10.     }   
  11.    
  12.     public MyListView (Context context, AttributeSet attrs, int defStyle) {   
  13.           super(context, attrs, defStyle);   
  14.     }   
  15.    
  16.     public MyListView (Context context) {   
  17.           super(context);   
  18.     }   
  19.    
  20.     @Override   
  21.     public boolean onTouchEvent(MotionEvent event) {   
  22.          switch (event.getAction()) {   
  23.               case MotionEvent.ACTION_DOWN:   
  24.                    if (mLastDownY == 0f && mDistance == 0) {   
  25.                          mLastDownY = event.getY();   
  26.                    return true;   
  27.               }   
  28.               break;   
  29.    
  30.     case MotionEvent.ACTION_CANCEL:   
  31.            break;  
  32.   
  33.     case MotionEvent.ACTION_UP:   
  34.           if (mDistance != 0) {   
  35.            mStep = 1;   
  36.            mPositive = (mDistance >= 0);   
  37.            this.post(this);   
  38.            return true;   
  39.         }   
  40.         mLastDownY = 0f;   
  41.         mDistance = 0;   
  42.         break;   
  43.    
  44.     case MotionEvent.ACTION_MOVE:   
  45.         if (mLastDownY != 0f) {   
  46.               mDistance = (int) (mLastDownY - event.getY());   
  47.               if ((mDistance 0 && getFirstVisiblePosition() == 0 && getChildAt(0).getTop() == 0) || (mDistance > 0 && getLastVisiblePosition() == getCount() - 1)) {   
  48.                    mDistance /= 2;   
  49.                    scrollTo(0, mDistance);   
  50.                    return true;   
  51.                }   
  52.         }   
  53.         mDistance = 0;   
  54.         break;   
  55.         }   
  56.         return super.onTouchEvent(event);   
  57.     }   
  58.    
  59.     public void run() {   
  60.           mDistance += mDistance > 0 ? -mStep : mStep;   
  61.           scrollTo(0, mDistance);   
  62.           if ((mPositive && mDistance <= 0) || (!mPositive && mDistance >= 0)) {   
  63.                 scrollTo(0, 0);   
  64.                 mDistance = 0;   
  65.                 mLastDownY = 0f;   
  66.                 return;   
  67.            }   
  68.           mStep += 1;   
  69.           this.postDelayed(this, 10);   
  70.      }   
  71. }   

    然后看一下xml的布局:

 

 

[html] view plaincopy
 
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:orientation="horizontal"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent" >  
  6.   
  7.     <com.example.multilistview.MyListView  
  8.                 android:id="@+id/listView"  
  9.                 android:layout_width="wrap_content"  
  10.                 android:layout_height="wrap_content"  
  11.                 android:layout_weight="1"   
  12.                 android:choiceMode="singleChoice"  
  13.                 android:scrollbars="none"  
  14.                 android:divider="@drawable/listitem_divide"  
  15.                 android:listSelector="#00000000"  
  16.                 android:background="#e4e3de"  
  17.                 >  
  18.             </com.example.multilistview.MyListView>  
  19.                   
  20.              <com.example.multilistview.MyListView  
  21.                 android:id="@+id/subListView"  
  22.                 android:layout_width="wrap_content"  
  23.                 android:layout_height="wrap_content"   
  24.                 android:layout_weight="1"  
  25.                 android:background="#e4e3de"  
  26.                  >  
  27.                       
  28.                 </com.example.multilistview.MyListView>   
  29.       
  30.   
  31. </LinearLayout>  


     两个自定义的listview  横向布局,然后是父listview的适配器

 

 

[html] view plaincopy
 
  1. public class MyAdapter extends BaseAdapter {  
  2.   
  3.     Context context;  
  4.     LayoutInflater inflater;  
  5.     String [] foods;  
  6.     int last_item;  
  7.     int [] images;  
  8.     private int selectedPosition = -1;       
  9.     public MyAdapter(Context context,String [] foods,int[] images){  
  10.         this.context = context;  
  11.         this.foods = foods;  
  12.         this.images = images;  
  13.         inflater=LayoutInflater.from(context);  
  14.     }  
  15.       
  16.     @Override  
  17.     public int getCount() {  
  18.         // TODO Auto-generated method stub  
  19.         return foods.length;  
  20.     }  
  21.   
  22.     @Override  
  23.     public Object getItem(int position) {  
  24.         // TODO Auto-generated method stub  
  25.         return position;  
  26.     }  
  27.   
  28.     @Override  
  29.     public long getItemId(int position) {  
  30.         // TODO Auto-generated method stub  
  31.         return position;  
  32.     }  
  33.   
  34.     @Override  
  35.     public View getView(int position, View convertView, ViewGroup parent) {  
  36.         // TODO Auto-generated method stub  
  37.         ViewHolder  holder = null;  
  38.         if(convertView==null){  
  39.         convertView = inflater.inflate(R.layout.mylist_item, null);  
  40.         holder = new ViewHolder();  
  41.         holder.textView =(TextView)convertView.findViewById(R.id.textview);  
  42.         holder.imageView =(ImageView)convertView.findViewById(R.id.imageview);  
  43.         holder.layout=(LinearLayout)convertView.findViewById(R.id.colorlayout);  
  44.         convertView.setTag(holder);  
  45.         }  
  46.         else{  
  47.         holder=(ViewHolder)convertView.getTag();  
  48.         }  
  49.         // 设置选中效果      
  50.          if(selectedPosition == position)     
  51.         {     
  52.              holder.textView.setTextColor(Color.BLUE);     
  53.   
  54.           
  55.          holder.layout.setBackgroundColor(Color.LTGRAY);     
  56.        } else {     
  57.            holder.textView.setTextColor(Color.WHITE);     
  58.         holder.layout.setBackgroundColor(Color.TRANSPARENT);     
  59.          }     
  60.   
  61.          
  62.         holder.textView.setText(foods[position]);  
  63.         holder.textView.setTextColor(Color.BLACK);  
  64.         holder.imageView.setBackgroundResource(images[position]);  
  65.           
  66.         return convertView;  
  67.     }  
  68.   
  69.     public static class ViewHolder{  
  70.         public TextView textView;  
  71.         public ImageView  imageView;  
  72.         public LinearLayout layout;  
  73.     }  
  74.   
  75.     public void setSelectedPosition(int position) {     
  76.        selectedPosition = position;     
  77.     }     
  78.   
  79. }  

  对应的 item布局:

 

 

[html] view plaincopy
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@+id/colorlayout"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent" >  
  6.   
  7.     <ImageView  
  8.     android:id="@+id/imageview"  
  9.     android:layout_width="wrap_content"  
  10.     android:layout_height="wrap_content"  
  11.     android:layout_marginLeft="10dip"  
  12.     android:layout_marginTop="5dip"  
  13.     />  
  14.     <TextView   
  15.     android:id="@+id/textview"  
  16.     android:layout_width="wrap_content"  
  17.     android:layout_height="wrap_content"  
  18.     android:text=""  
  19.     android:textSize="16dip"  
  20.     android:layout_marginTop="8dip"  
  21.     android:layout_marginLeft="8dip"  
  22.     android:layout_marginBottom="8dip"/>  
  23.    <!--  android:background="@drawable/selector"  自定义listview 样式-->  
  24. </LinearLayout>  


    然后是子适配器代码:

 

 

[html] view plaincopy
 
  1. public class SubAdapter extends BaseAdapter {  
  2.       
  3.     Context context;  
  4.     LayoutInflater layoutInflater;  
  5.     String[][] cities;  
  6.     public int foodpoition;  
  7.   
  8.     public SubAdapter(Context context, String[][] cities,int position) {  
  9.         this.context = context;  
  10.         this.cities = cities;  
  11.         layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
  12.         this.foodpoition = position;  
  13.     }  
  14.   
  15.     @Override  
  16.     public int getCount() {  
  17.         // TODO Auto-generated method stub  
  18.         return cities.length;  
  19.     }  
  20.   
  21.     @Override  
  22.     public Object getItem(int position) {  
  23.         // TODO Auto-generated method stub  
  24.         return getItem(position);  
  25.     }  
  26.   
  27.     @Override  
  28.     public long getItemId(int position) {  
  29.         // TODO Auto-generated method stub  
  30.         return position;  
  31.     }  
  32.   
  33.     @Override  
  34.     public View getView(int position, View convertView, ViewGroup parent) {  
  35.         // TODO Auto-generated method stub  
  36.         ViewHolder viewHolder = null;  
  37.         final int location=position;  
  38.         if (convertView == null) {  
  39.             convertView = layoutInflater.inflate(R.layout.sublist_item, null);  
  40.             viewHolder = new ViewHolder();  
  41.             viewHolder.textView = (TextView) convertView  
  42.                     .findViewById(R.id.textview1);  
  43.             convertView.setTag(viewHolder);  
  44.         } else {  
  45.             viewHolder = (ViewHolder) convertView.getTag();  
  46.         }  
  47.         viewHolder.textView.setText(cities[foodpoition][position]);  
  48.         viewHolder.textView.setTextColor(Color.BLACK);  
  49.           
  50.         return convertView;  
  51.     }  
  52.   
  53.     public static class ViewHolder {  
  54.         public TextView textView;  
  55.     }  
  56.   
  57. }  


   对应的xml布局:

 

  

[html] view plaincopy
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="wrap_content"  
  4.     android:layout_height="wrap_content"  
  5.      
  6.     >  
  7.      <TextView   
  8.     android:id="@+id/textview1"  
  9.     android:layout_width="wrap_content"  
  10.     android:layout_height="wrap_content"  
  11.     android:text="aaaaa"  
  12.     android:textSize="16dip"  
  13.     android:layout_marginTop="10dip"  
  14.     android:layout_marginLeft="8dip"  
  15.     android:layout_marginBottom="8dip"/>  
  16. </LinearLayout>  

    
     最后看下主activity的实现代码

 

 

[html] view plaincopy
 
  1. public class MainActivity extends Activity {  
  2.       
  3.     private MyListView listView;   
  4.     private MyListView subListView;  
  5.     private MyAdapter myAdapter;  
  6.     private SubAdapter subAdapter;  
  7.       
  8.     String cities[][] = new String[][] {  
  9.             new String[] {"全部美食", "本帮江浙菜", "川菜", "粤菜", "湘菜","东北菜","台湾菜","新疆/清真","素菜","火锅","自助餐","小吃快餐","日本","韩国料理",  
  10.             "东南亚菜","西餐","面包甜点","其他"},  
  11.             new String[] {"全部休闲娱乐","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",  
  12.                 "DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"},  
  13.             new String[] {"全部购物", "综合商场", "服饰鞋包", "运动户外","珠宝饰品","化妆品","数码家电","亲子购物","家居建材"  
  14.                 ,"书店","书店","眼镜店","特色集市","更多购物场所","食品茶酒","超市/便利店","药店"},  
  15.             new String[] {"全部休闲娱乐","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",  
  16.                     "DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"},  
  17.             new String[] {"全","咖啡厅","酒吧","茶馆","KTV","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",  
  18.                     "DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"},  
  19.             new String[] {"全部","咖啡厅","酒吧","茶馆","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",  
  20.                     "DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"},  
  21.             new String[] {"全部休","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",  
  22.                     "DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"},  
  23.             new String[] {"全部休闲","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",  
  24.                     "DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"},  
  25.             new String[] {"全部休闲娱","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",  
  26.                     "DIY手工坊","桌球馆","桌面游戏"},  
  27.             new String[] {"全部休闲娱乐","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",  
  28.                     "DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"},  
  29.             new String[] {"全部休闲aaa","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",  
  30.                     "DIY手工坊","桌球馆","桌面游戏"},  
  31.             };  
  32.         String foods[] =new String []{"全部频道","美食","休闲娱乐","购物","酒店","丽人","运动健身","结婚","亲子","爱车","生活服务"};  
  33.         int images[] = new int[]{R.drawable.ic_category_0,R.drawable.ic_category_10,R.drawable.ic_category_30,R.drawable.ic_category_20  
  34.                 ,R.drawable.ic_category_60,R.drawable.ic_category_50,R.drawable.ic_category_45,R.drawable.ic_category_50,R.drawable.ic_category_70,  
  35.                 R.drawable.ic_category_65,R.drawable.ic_category_80};  
  36.       
  37.     @Override  
  38.     public void onCreate(Bundle savedInstanceState) {  
  39.         super.onCreate(savedInstanceState);  
  40.         setContentView(R.layout.activity_main);  
  41.           
  42.         init();  
  43.         myAdapter=new MyAdapter(getApplicationContext(), foods, images);  
  44.         listView.setAdapter(myAdapter);  
  45.       
  46.         selectDefult();  
  47.           
  48.         listView.setOnItemClickListener(new OnItemClickListener() {  
  49.   
  50.             @Override  
  51.             public void onItemClick(AdapterView<?> arg0, View arg1, int position,  
  52.                     long arg3) {  
  53.                 // TODO Auto-generated method stub  
  54.                 final int location=position;  
  55.                 myAdapter.setSelectedPosition(position);  
  56.                 myAdapter.notifyDataSetInvalidated();  
  57.                 subAdapter=new SubAdapter(getApplicationContext(), cities, position);  
  58.                 subListView.setAdapter(subAdapter);  
  59.                 subListView.setOnItemClickListener(new OnItemClickListener() {  
  60.   
  61.                     @Override  
  62.                     public void onItemClick(AdapterView<?> arg0, View arg1,  
  63.                             int position, long arg3) {  
  64.                         // TODO Auto-generated method stub  
  65.                         Toast.makeText(getApplicationContext(), cities[location][position], Toast.LENGTH_SHORT).show();  
  66.                     }  
  67.                 });  
  68.             }  
  69.         });  
  70.           
  71.     }  
  72.    private void init(){  
  73.        listView=(MyListView) findViewById(R.id.listView);  
  74.        subListView=(MyListView) findViewById(R.id.subListView);  
  75.    }  
  76.      
  77.    private void selectDefult(){  
  78.        final int location=0;  
  79.             myAdapter.setSelectedPosition(0);  
  80.             myAdapter.notifyDataSetInvalidated();  
  81.             subAdapter=new SubAdapter(getApplicationContext(), cities, 0);  
  82.             subListView.setAdapter(subAdapter);  
  83.             subListView.setOnItemClickListener(new OnItemClickListener() {  
  84.   
  85.                 @Override  
  86.                 public void onItemClick(AdapterView<?> arg0, View arg1,  
  87.                         int position, long arg3) {  
  88.                     // TODO Auto-generated method stub  
  89.                     Toast.makeText(getApplicationContext(), cities[location][position], Toast.LENGTH_SHORT).show();  
  90.                 }  
  91.             });  
  92.    }  
  93.     
  94. }  


        默认我选中了第0个,下面看一下运行效果:

 

 

【转】http://blog.csdn.net/wangkuifeng0118/article/details/8446661