listView多个viewType,listView多个类型的item

最近在项目中需要对listview中的数据进行分组,我构思的基本原理就是,在适配器Adapter的getView()方法中,根据当前item类型,分别加载不同的布局,这样是很容易实现的,想必大家都很清楚这个小东西。但是问题是,这样的代码写下来listview在数据很多时,上下滑动会很卡,于是乎就想到了用viewHolder来进行缓存, 难度就在对不同的item进行不同的缓存。

下面是我实现的效果:



第1、 2,3 、 4,5,6 、7、 8,9、  10,11,12......如此循环下去,下面是我实现的代码:


public class listViewTest extends Activity {
    /** Called when the activity is first created. */
	ListView listView;
	MyAdapter listAdapter;
	ArrayList<String> listString;
 	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        listView = (ListView)this.findViewById(R.id.listview);
        listString = new ArrayList<String>();
        for(int i = 0 ; i < 100 ; i++)
        {
        	listString.add(Integer.toString(i));
        }
        listAdapter = new MyAdapter(this);
        listView.setAdapter(listAdapter);
    }

class MyAdapter extends BaseAdapter{

	Context mContext;
	LinearLayout linearLayout = null;
	LayoutInflater inflater;
	TextView tex;
	final int VIEW_TYPE = 3;
	final int TYPE_1 = 0;
	final int TYPE_2 = 1;
	final int TYPE_3 = 2;
	
	public MyAdapter(Context context) {
		// TODO Auto-generated constructor stub
		mContext = context;
		inflater = LayoutInflater.from(mContext);
	}

	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return listString.size();
	}

	//每个convert view都会调用此方法,获得当前所需要的view样式
	@Override
	public int getItemViewType(int position) {
		// TODO Auto-generated method stub
		int p = position%6;
		if(p == 0)
			return TYPE_1;
		else if(p < 3)
			return TYPE_2;
		else if(p < 6)
			return TYPE_3;
		else
			return TYPE_1;
		
	}

	@Override
	public int getViewTypeCount() {
		// TODO Auto-generated method stub
		return 3;
	}

	@Override
	public Object getItem(int arg0) {
		// TODO Auto-generated method stub
		return listString.get(arg0);
	}

	@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
		viewHolder1 holder1 = null;
		viewHolder2 holder2 = null;
		viewHolder3 holder3 = null;
		int type = getItemViewType(position);
		
		
		//无convertView,需要new出各个控件
		if(convertView == null)
		{	
			Log.e("convertView = ", " NULL");
			
			//按当前所需的样式,确定new的布局
			switch(type)
			{
			case TYPE_1:
				convertView = inflater.inflate(R.layout.listitem1, parent, false);
				holder1 = new viewHolder1();
				holder1.textView = (TextView)convertView.findViewById(R.id.textview1);
				holder1.checkBox = (CheckBox)convertView.findViewById(R.id.checkbox);
				Log.e("convertView = ", "NULL TYPE_1");
				convertView.setTag(holder1);
				break;
			case TYPE_2:
				convertView = inflater.inflate(R.layout.listitem2, parent, false);
				holder2 = new viewHolder2();
				holder2.textView = (TextView)convertView.findViewById(R.id.textview2);
				Log.e("convertView = ", "NULL TYPE_2");
				convertView.setTag(holder2);
				break;
			case TYPE_3:
				convertView = inflater.inflate(R.layout.listitem3, parent, false);
				holder3 = new viewHolder3();
				holder3.textView = (TextView)convertView.findViewById(R.id.textview3);
				holder3.imageView = (ImageView)convertView.findViewById(R.id.imageview);
				Log.e("convertView = ", "NULL TYPE_3");
				convertView.setTag(holder3);
				break;
			}
		}
		else
		{
			//有convertView,按样式,取得不用的布局
			switch(type)
			{
			case TYPE_1:
				holder1 = (viewHolder1) convertView.getTag();
				Log.e("convertView !!!!!!= ", "NULL TYPE_1");
				break;
			case TYPE_2:
				holder2 = (viewHolder2) convertView.getTag();
				Log.e("convertView !!!!!!= ", "NULL TYPE_2");
				break;
			case TYPE_3:
				holder3 = (viewHolder3) convertView.getTag();
				Log.e("convertView !!!!!!= ", "NULL TYPE_3");
				break;
			}
		}

		//设置资源
		switch(type)
		{
			case TYPE_1:
				holder1.textView.setText(Integer.toString(position));
				holder1.checkBox.setChecked(true);
				break;
			case TYPE_2:
				holder2.textView.setText(Integer.toString(position));
				break;
			case TYPE_3:
				holder3.textView.setText(Integer.toString(position));
				holder3.imageView.setBackgroundResource(R.drawable.icon);
				break;
		}
		
		
		return convertView;
	}
	
}


//各个布局的控件资源

class viewHolder1{
	CheckBox checkBox;
	TextView textView;
}
class viewHolder2{
	TextView textView;
}
class viewHolder3{
	ImageView imageView;
	TextView textView;
}
}


getViewTypeCoun
在看了AbsListView.java的源代码发现,在ObtainView()方法中,它会来判断当前litview中的type个数,也就是我复写getViewTypeCount()的原因,我们这里有三个不同的item布局,他们都被缓存了起来,所以在getview()方法中,当上下滑动时,就没有必要再重新做inflate和findViewById()的工作,直接使用回收来的viewHolder对象,大大的提高了listview滑动的流畅性。

在Android中,ListView通常用于显示一列可滚动的内容,如果要实现多个宫格(Grid View)并且内容能根据屏幕宽度自适应换行,你需要使用`GridView`或`RecyclerView`配合`GridLayoutManager`。`GridLayoutManager`允许你在列表视图中创建网格布局,每个网格中的项目会自动换行以适应屏幕宽度。 以下是实现步骤: 1. **引入依赖**: 如果你使用的是`RecyclerView`,确保已经添加了RecyclerView库: ```xml <implementation 'androidx.recyclerview:recyclerview:1.3.0' /> ``` 2. **创建布局文件**: 使用`ConstraintLayout`或者`LinearLayout`作为根布局,创建一个`GridView`或`RecyclerView`作为主要容器。设置`columnCount`属性,如 `android:numColumns="auto_fit"`(让系统自动调整列数)。 ```xml <androidx.recyclerview.widget.RecyclerView android:id="@+id/grid_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:numColumns="auto_fit" /> ``` 3. **创建Adapter**: 使用`GridLayoutManager`初始化`RecyclerView`的适配器,确保在`onCreateViewHolder`方法中为每个单元格分配正确的布局,并设置宽高比例。 ```java GridLayoutManager layoutManager = new GridLayoutManager(context, GridLayoutManager.AUTO_FIT); recyclerView.setLayoutManager(layoutManager); @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { // 创建并返回ViewHolder,使用合适的布局 View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_grid, parent, false); return new GridViewHolder(itemView); } // ... 实现其他适配器方法,如 onBindViewHolder() ``` 4. **自适应布局**: 在`item_grid.xml`布局文件中,确保子视图(例如`ImageView`, `TextView`等)使用百分比宽度或 wrap_content 以适应网格布局的变化。 ```xml <ImageView android:layout_width="0dp" android:layout_weight="1" android:src="@drawable/your_image" /> ``` 5. **调整网格大小**: 可以根据需要在运行时调整网格大小,例如,当屏幕尺寸变化时,通过监听屏幕变化事件来动态设置`columnCount`。 ```java // 获取屏幕宽度 DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); int screenWidth = metrics.widthPixels; // 更新列数 layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { return screenWidth <= YOUR_BREAKPOINT ? 1 : AUTO_FIT; } }); ```
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值