android二级listview列表实现代码(高仿大众点评)



今天来实现以下大众点评客户端的横向listview二级列表,先看一下样式。

 

这种横向的listview二级列表在手机软件上还不太常见,但是使用过平板的都应该知道,在平板上市比较常见的。可能是因为平板屏幕比较大,而且也能展现更多的内容。
下面来看一下我的实现步骤。
首先自定义一个listview,代码如下:

public class MyListView extends ListView implements Runnable { 
private float mLastDownY = 0f; 
private int mDistance = 0; 
private int mStep = 10; 
private boolean mPositive = false; 
public MyListView (Context context, AttributeSet attrs) { 
super(context, attrs); 
} 
public MyListView (Context context, AttributeSet attrs, int defStyle) { 
super(context, attrs, defStyle); 
} 
public MyListView (Context context) { 
super(context); 
} 
@Override 
public boolean onTouchEvent(MotionEvent event) { 
switch (event.getAction()) { 
case MotionEvent.ACTION_DOWN: 
if (mLastDownY == 0f && mDistance == 0) { 
mLastDownY = event.getY(); 
return true; 
} 
break; 
case MotionEvent.ACTION_CANCEL: 
break; 
case MotionEvent.ACTION_UP: 
if (mDistance != 0) { 
mStep = 1; 
mPositive = (mDistance >= 0); 
this.post(this); 
return true; 
} 
mLastDownY = 0f; 
mDistance = 0; 
break; 
case MotionEvent.ACTION_MOVE: 
if (mLastDownY != 0f) { 
mDistance = (int) (mLastDownY - event.getY()); 
if ((mDistance < 0 && getFirstVisiblePosition() == 0 && getChildAt(0).getTop() == 0) || (mDistance > 0 && getLastVisiblePosition() == getCount() - 1)) { 
mDistance /= 2; 
scrollTo(0, mDistance); 
return true; 
} 
} 
mDistance = 0; 
break; 
} 
return super.onTouchEvent(event); 
} 
public void run() { 
mDistance += mDistance > 0 ? -mStep : mStep; 
scrollTo(0, mDistance); 
if ((mPositive && mDistance <= 0) || (!mPositive && mDistance >= 0)) { 
scrollTo(0, 0); 
mDistance = 0; 
mLastDownY = 0f; 
return; 
} 
mStep += 1; 
this.postDelayed(this, 10); 
} 
} 


然后看一下xml的布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:orientation="horizontal" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" > 
<com.example.multilistview.MyListView 
android:id="@+id/listView" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:layout_weight="1" 
android:choiceMode="singleChoice" 
android:scrollbars="none" 
android:divider="@drawable/listitem_divide" 
android:listSelector="#00000000" 
android:background="#e4e3de" 
> 
</com.example.multilistview.MyListView> 

<com.example.multilistview.MyListView 
android:id="@+id/subListView" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:layout_weight="1" 
android:background="#e4e3de" 
> 

</com.example.multilistview.MyListView> 
</LinearLayout> 


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

public class MyAdapter extends BaseAdapter { 
Context context; 
LayoutInflater inflater; 
String [] foods; 
int last_item; 
int [] images; 
private int selectedPosition = -1; 
public MyAdapter(Context context,String [] foods,int[] images){ 
this.context = context; 
this.foods = foods; 
this.images = images; 
inflater=LayoutInflater.from(context); 
} 

@Override 
public int getCount() { 
// TODO Auto-generated method stub 
return foods.length; 
} 
@Override 
public Object getItem(int position) { 
// TODO Auto-generated method stub 
return position; 
} 
@Override 
public long getItemId(int position) { 
// TODO Auto-generated method stub 
return position; 
} 
@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
// TODO Auto-generated method stub 
ViewHolder holder = null; 
if(convertView==null){ 
convertView = inflater.inflate(R.layout.mylist_item, null); 
holder = new ViewHolder(); 
holder.textView =(TextView)convertView.findViewById(R.id.textview); 
holder.imageView =(ImageView)convertView.findViewById(R.id.imageview); 
holder.layout=(LinearLayout)convertView.findViewById(R.id.colorlayout); 
convertView.setTag(holder); 
} 
else{ 
holder=(ViewHolder)convertView.getTag(); 
} 
// 设置选中效果 
if(selectedPosition == position) 
{ 
holder.textView.setTextColor(Color.BLUE); 

holder.layout.setBackgroundColor(Color.LTGRAY); 
} else { 
holder.textView.setTextColor(Color.WHITE); 
holder.layout.setBackgroundColor(Color.TRANSPARENT); 
} 

holder.textView.setText(foods[position]); 
holder.textView.setTextColor(Color.BLACK); 
holder.imageView.setBackgroundResource(images[position]); 

return convertView; 
} 
public static class ViewHolder{ 
public TextView textView; 
public ImageView imageView; 
public LinearLayout layout; 
} 
public void setSelectedPosition(int position) { 
selectedPosition = position; 
} 
} 


对应的 item布局:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/colorlayout" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" > 
<ImageView 
android:id="@+id/imageview" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:layout_marginLeft="10dip" 
android:layout_marginTop="5dip" 
/> 
<TextView 
android:id="@+id/textview" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:text="" 
android:textSize="16dip" 
android:layout_marginTop="8dip" 
android:layout_marginLeft="8dip" 
android:layout_marginBottom="8dip"/> 
<!-- android:background="@drawable/selector" 自定义listview 样式--> 
</LinearLayout> 


然后是子适配器代码:

public class SubAdapter extends BaseAdapter { 

Context context; 
LayoutInflater layoutInflater; 
String[][] cities; 
public int foodpoition; 
public SubAdapter(Context context, String[][] cities,int position) { 
this.context = context; 
this.cities = cities; 
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
this.foodpoition = position; 
} 
@Override 
public int getCount() { 
// TODO Auto-generated method stub 
return cities.length; 
} 
@Override 
public Object getItem(int position) { 
// TODO Auto-generated method stub 
return getItem(position); 
} 
@Override 
public long getItemId(int position) { 
// TODO Auto-generated method stub 
return position; 
} 
@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
// TODO Auto-generated method stub 
ViewHolder viewHolder = null; 
final int location=position; 
if (convertView == null) { 
convertView = layoutInflater.inflate(R.layout.sublist_item, null); 
viewHolder = new ViewHolder(); 
viewHolder.textView = (TextView) convertView 
.findViewById(R.id.textview1); 
convertView.setTag(viewHolder); 
} else { 
viewHolder = (ViewHolder) convertView.getTag(); 
} 
viewHolder.textView.setText(cities[foodpoition][position]); 
viewHolder.textView.setTextColor(Color.BLACK); 

return convertView; 
} 
public static class ViewHolder { 
public TextView textView; 
} 
} 


对应的xml布局:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
> 
<TextView 
android:id="@+id/textview1" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:text="aaaaa" 
android:textSize="16dip" 
android:layout_marginTop="10dip" 
android:layout_marginLeft="8dip" 
android:layout_marginBottom="8dip"/> 
</LinearLayout> 

最后看下主activity的实现代码
public class MainActivity extends Activity { 
private MyListView listView; 
private MyListView subListView; 
private MyAdapter myAdapter; 
private SubAdapter subAdapter; 

String cities[][] = new String[][] { 
new String[] {"全部美食", "本帮江浙菜", "川菜", "粤菜", "湘菜","东北菜","台湾菜","新疆/清真","素菜","火锅","自助餐","小吃快餐","日本","韩国料理", 
"东南亚菜","西餐","面包甜点","其他"}, 
new String[] {"全部休闲娱乐","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术", 
"DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"}, 
new String[] {"全部购物", "综合商场", "服饰鞋包", "运动户外","珠宝饰品","化妆品","数码家电","亲子购物","家居建材" 
,"书店","书店","眼镜店","特色集市","更多购物场所","食品茶酒","超市/便利店","药店"}, 
new String[] {"全部休闲娱乐","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术", 
"DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"}, 
new String[] {"全","咖啡厅","酒吧","茶馆","KTV","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术", 
"DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"}, 
new String[] {"全部","咖啡厅","酒吧","茶馆","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术", 
"DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"}, 
new String[] {"全部休","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术", 
"DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"}, 
new String[] {"全部休闲","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术", 
"DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"}, 
new String[] {"全部休闲娱","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术", 
"DIY手工坊","桌球馆","桌面游戏"}, 
new String[] {"全部休闲娱乐","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术", 
"DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"}, 
new String[] {"全部休闲aaa","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术", 
"DIY手工坊","桌球馆","桌面游戏"}, 
}; 
String foods[] =new String []{"全部频道","美食","休闲娱乐","购物","酒店","丽人","运动健身","结婚","亲子","爱车","生活服务"}; 
int images[] = new int[]{R.drawable.ic_category_0,R.drawable.ic_category_10,R.drawable.ic_category_30,R.drawable.ic_category_20 
,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, 
R.drawable.ic_category_65,R.drawable.ic_category_80}; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.activity_main); 
init(); 
myAdapter=new MyAdapter(getApplicationContext(), foods, images); 
listView.setAdapter(myAdapter); 
selectDefult(); 
listView.setOnItemClickListener(new OnItemClickListener() { 
@Override 
public void onItemClick(AdapterView<?> arg0, View arg1, int position, 
long arg3) { 
// TODO Auto-generated method stub 
final int location=position; 
myAdapter.setSelectedPosition(position); 
myAdapter.notifyDataSetInvalidated(); 
subAdapter=new SubAdapter(getApplicationContext(), cities, position); 
subListView.setAdapter(subAdapter); 
subListView.setOnItemClickListener(new OnItemClickListener() { 
@Override 
public void onItemClick(AdapterView<?> arg0, View arg1, 
int position, long arg3) { 
// TODO Auto-generated method stub 
Toast.makeText(getApplicationContext(), cities[location][position], Toast.LENGTH_SHORT).show(); 
} 
}); 
} 
}); 
} 
private void init(){ 
listView=(MyListView) findViewById(R.id.listView); 
subListView=(MyListView) findViewById(R.id.subListView); 
} 
private void selectDefult(){ 
final int location=0; 
myAdapter.setSelectedPosition(0); 
myAdapter.notifyDataSetInvalidated(); 
subAdapter=new SubAdapter(getApplicationContext(), cities, 0); 
subListView.setAdapter(subAdapter); 
subListView.setOnItemClickListener(new OnItemClickListener() { 
@Override 
public void onItemClick(AdapterView<?> arg0, View arg1, 
int position, long arg3) { 
// TODO Auto-generated method stub 
Toast.makeText(getApplicationContext(), cities[location][position], Toast.LENGTH_SHORT).show(); 
} 
}); 
} 
} 
默认我选中了第0个,下面看一下运行效果:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值