zoukankan      html  css  js  c++  java
  • android RecycleView复杂多条目的布局

    用RecycleView来实现布局形式。默认仅仅能指定一种布局格式。可是实际中我们的布局常常会用到多种类型的布局方式。怎样实现呢?

    今天来说下经常使用的2钟方式。

    第一种:

    通过自己定义addHeadView方法来加入头布局

    RecycleViewWithHead.java

    import android.app.Activity;
    import android.os.Bundle;
    import android.support.v7.widget.GridLayoutManager;
    import android.support.v7.widget.GridLayoutManager.SpanSizeLookup;
    import android.support.v7.widget.RecyclerView;
    import android.view.View;
    
    public class RecycleViewWithHead extends Activity {
    
    	private RecyclerView rcv;
    	// 当前的条目是recyclerView的头布局
    	public static final int HEADER_RECYCLER_VIEW_ITEM = 0;
    	// 当前的条目是普通recyclerView的条目
    	public static final int NORMAL_RECYCLER_VIEW_ITEM = 1;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		// TODO Auto-generated method stub
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_recycle);
    		rcv = (RecyclerView) findViewById(R.id.rcv);
    		// 设置布局管理
    		GridLayoutManager manager = new GridLayoutManager(this, 2);
    		// 设置布局管理一条数据占用几行,假设是头布局则头布局自己占用一行
    		manager.setSpanSizeLookup(new SpanSizeLookup() {
    			@Override
    			public int getSpanSize(int postion) {
    				if (postion == 0) {
    					return 2;
    				} else {
    					return 1;
    				}
    			}
    		});
    		rcv.setLayoutManager(manager);
    		MyRecycleAdapter adapter = new MyRecycleAdapter(
    				RecycleViewWithHead.this, 20);
    		View view = View.inflate(this, R.layout.head, null);
    		adapter.addHeadView(view);
    		rcv.setAdapter(adapter);
    	}
    }
    


    布局文件activity_recycle.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/rcv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
    
    </RelativeLayout>


    头布局文件head.xml

    <?

    xml version="1.0" encoding="utf-8"?

    > <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/iv_head" android:layout_width="80dp" android:layout_height="80dp" android:layout_margin="10dp" android:src="@drawable/head" /> <TextView android:id="@+id/tv_head" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/iv_head" android:layout_toRightOf="@+id/iv_head" android:text="这是一张熊猫的图片" /> <ImageView android:id="@+id/iv_head_bottom" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/iv_head" android:layout_toRightOf="@+id/iv_head" android:src="@drawable/type" /> </RelativeLayout>



    适配器MyRecycleAdapter.java

    import android.content.Context;
    import android.support.v7.widget.RecyclerView;
    import android.support.v7.widget.RecyclerView.ViewHolder;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.widget.Toast;
    
    public class MyRecycleAdapter extends
    		RecyclerView.Adapter<MyRecycleAdapterHolder> {
    
    	private View headView;
    	private Context mContext;
    	private int count;
    
    	MyRecycleAdapter(Context mContext, int count) {
    		this.count = count;
    		this.mContext = mContext;
    	}
    
    	/**
    	 * 设置数据源总的条目
    	 */
    	@Override
    	public int getItemCount() {
    		//返回条目数加头布局个数
    		return count + 1;
    	}
    
    	@Override
    	public void onBindViewHolder(MyRecycleAdapterHolder holder,
    			final int position) {
    		int itemViewType = getItemViewType(position);
    		// 头部
    		if (itemViewType == RecycleViewWithHead.HEADER_RECYCLER_VIEW_ITEM) {
    			return;
    		} else if (itemViewType == RecycleViewWithHead.NORMAL_RECYCLER_VIEW_ITEM) {//普通条目
    			holder.iv_item_icon.setOnClickListener(new OnClickListener() {
    				@Override
    				public void onClick(View v) {
    					Toast.makeText(mContext, (position - 1) + "", 0).show();
    				}
    			});
    		}
    
    	}
    
    	@Override
    	public MyRecycleAdapterHolder onCreateViewHolder(ViewGroup parent,
    			int viewType) {
    		View root = null;
    		if (viewType == RecycleViewWithHead.HEADER_RECYCLER_VIEW_ITEM) {
    			root = headView;
    		} else {
    			root = LayoutInflater.from(mContext).inflate(R.layout.item, parent,
    					false);
    		}
    		return new MyRecycleAdapterHolder(root, viewType);
    	}
    
    	/**
    	 * 加入自己定义头部
    	 */
    	public void addHeadView(View view) {
    		this.headView = view;
    	}
    
    	@Override
    	public int getItemViewType(int position) {
    
    		if (position == 0) {
    			return RecycleViewWithHead.HEADER_RECYCLER_VIEW_ITEM;
    		} else {
    			return RecycleViewWithHead.NORMAL_RECYCLER_VIEW_ITEM;
    		}
    	}
    }
    


    普通条目的布局文件item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/ll_list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="2dp"
        android:layout_marginRight="2dp"
        android:layout_marginTop="5dp"
        android:orientation="vertical" >
    
        <ImageView
            android:id="@+id/iv_item_icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/item" />
    
        <TextView
            android:id="@+id/tv_item"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="5dp"
            android:text="这是一仅仅熊猫" />
    
    </LinearLayout>



    普通条目的ViewHolder

    import android.support.v7.widget.RecyclerView;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    public class MyRecycleAdapterHolder extends RecyclerView.ViewHolder{
    	
    	public ImageView iv_item_icon;
    	public TextView tv_item;
    	public MyRecycleAdapterHolder(View itemView) {
    		super(itemView);
    	}
    	public MyRecycleAdapterHolder(View itemView,int viewType) {
    		super(itemView);
    		initView(itemView,viewType);
    	}
    	private void initView(View itemView, int viewType) {
    		iv_item_icon = (ImageView) itemView.findViewById(R.id.iv_item_icon);
    		tv_item = (TextView) itemView.findViewById(R.id.tv_item);
    	}
    
    }
    

    效果图:




    另一种情况类似于淘宝的商品展示我们能够切换每行显示的数量,事实上也非常easy

    先看下要实现的效果:


    我先说下大致的实现思路:

    1.给adapter设置一个当前显示多行还是单行的标记。

    2.每次切换视图时重置标记。并重置RecycleView的LayoutManager。

    3.调用adapter.notifyItemRangeChanged(2, adapter.getItemCount());(第一个參数是动画開始的位置索引)

    好了再来看下RecycleViewWithHead.java

    import com.example.myrecycleviewdemo.adapter.MyRecycleAdapter;
    import android.app.Activity;
    import android.os.Bundle;
    import android.support.v7.widget.GridLayoutManager;
    import android.support.v7.widget.GridLayoutManager.SpanSizeLookup;
    import android.support.v7.widget.RecyclerView;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.ImageView;
    
    public class RecycleViewWithHead extends Activity implements OnClickListener {
    
    	private RecyclerView rcv;
    	// 当前的条目是recyclerView的头布局
    	public static final int HEADER_RECYCLER_VIEW_ITEM = 0;
    	// 当前的条目是普通recyclerView的条目
    	public static final int NORMAL_RECYCLER_VIEW_ITEM = 1;
    	// 一行显示一个
    	public static final int RECYCLER_VIEW_ITEM_SINGLE = 3;
    	// 一行显示两个
    	public static final int RECYCLER_VIEW_ITEM_DOUBLE = 4;
    	private ImageView iv_switch;// 视图转换
    	private MyRecycleAdapter adapter;
    	private GridLayoutManager manager;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		// TODO Auto-generated method stub
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_recycle);
    		rcv = (RecyclerView) findViewById(R.id.rcv);
    		iv_switch = (ImageView) findViewById(R.id.iv_switch);
    		iv_switch.setOnClickListener(this);
    		manager = new GridLayoutManager(this, 2);
    		// 设置布局管理一条数据占用几行,假设是头布局则头布局自己占用一行
    		manager.setSpanSizeLookup(new SpanSizeLookup() {
    			@Override
    			public int getSpanSize(int postion) {
    				if (postion == 0) {
    					return 2;
    				} else {
    					return 1;
    				}
    			}
    		});
    		rcv.setLayoutManager(manager);
    		adapter = new MyRecycleAdapter(RecycleViewWithHead.this, 20);
    		View view = View.inflate(this, R.layout.head, null);
    		// 设置当前ViewType
    		adapter.setSpanSize(RecycleViewWithHead.RECYCLER_VIEW_ITEM_DOUBLE);
    		adapter.addHeadView(view);
    		rcv.setAdapter(adapter);
    	}
    
    	@Override
    	public void onClick(View v) {
    		switch (v.getId()) {
    		case R.id.iv_switch:
    			changeRecycleViewList();
    			break;
    
    		default:
    			break;
    		}
    
    	}
    
    	/**
    	 * 改变RecycleView的显示列数
    	 */
    	private void changeRecycleViewList() {
    		if (adapter != null) {
    			int spanSize = adapter.getSpanSize();
    			// 当前一行显示一列
    			if (spanSize == RecycleViewWithHead.RECYCLER_VIEW_ITEM_SINGLE) {
    				manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
    					@Override
    					public int getSpanSize(int position) {
    						if (adapter.getItemViewType(position) == RecycleViewWithHead.HEADER_RECYCLER_VIEW_ITEM) {
    							return 2;
    						} else {
    							return 1;
    
    						}
    					}
    				});
    				adapter.setSpanSize(RecycleViewWithHead.RECYCLER_VIEW_ITEM_DOUBLE);
    			}
    			// 当前一行显示两列
    			else if (spanSize == RecycleViewWithHead.RECYCLER_VIEW_ITEM_DOUBLE) {
    				manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
    					@Override
    					public int getSpanSize(int position) {
    						if (adapter.getItemViewType(position) == RecycleViewWithHead.HEADER_RECYCLER_VIEW_ITEM) {
    							return 2;
    						} else {
    							return 2;
    						}
    					}
    				});
    				adapter.setSpanSize(RecycleViewWithHead.RECYCLER_VIEW_ITEM_SINGLE);
    			}
    			// 第一个參数是动画開始的位置索引
    			adapter.notifyItemRangeChanged(2, adapter.getItemCount());
    		}
    	}
    }


    布局文件activity_recycle.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/rcv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
        
        <ImageView 
            android:id="@+id/iv_switch"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
    		android:layout_alignParentTop="true"
            android:layout_alignParentRight="true"
            android:layout_margin="20dp"
            android:src="@drawable/more"
            />
    
    </RelativeLayout>


    适配器MyRecycleAdapter.java

    import com.example.myrecycleviewdemo.R;
    import com.example.myrecycleviewdemo.RecycleViewWithHead;
    import com.example.myrecycleviewdemo.R.layout;
    import android.content.Context;
    import android.support.v7.widget.RecyclerView;
    import android.support.v7.widget.RecyclerView.ViewHolder;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.widget.Toast;
    
    public class MyRecycleAdapter extends
    		RecyclerView.Adapter<MyRecycleAdapterHolder> {
    
    	public View headView;
    	public Context mContext;
    	public int count;
    	private int spanSize;// 当前每行显示几列
    
    	public MyRecycleAdapter(Context mContext, int count) {
    		this.count = count;
    		this.mContext = mContext;
    	}
    
    	/**
    	 * 设置数据源总的条目
    	 */
    	@Override
    	public int getItemCount() {
    		// 返回条目数加头布局个数
    		return count + 1;
    	}
    
    	@Override
    	public void onBindViewHolder(MyRecycleAdapterHolder holder,
    			final int position) {
    		int itemViewType = getItemViewType(position);
    		// 头部
    		if (itemViewType == RecycleViewWithHead.HEADER_RECYCLER_VIEW_ITEM) {
    			return;
    		} else {// 普通条目
    			if (itemViewType == RecycleViewWithHead.RECYCLER_VIEW_ITEM_DOUBLE) {// 一行两列视图
    				holder.iv_item_icon.setOnClickListener(new OnClickListener() {
    					@Override
    					public void onClick(View v) {
    						Toast.makeText(mContext, "2列。" + (position - 1) + "", 0)
    								.show();
    					}
    				});
    			} else if (itemViewType == RecycleViewWithHead.RECYCLER_VIEW_ITEM_SINGLE) {// 一行一列视图
    				holder.iv_item_icon_single.setOnClickListener(new OnClickListener() {
    					@Override
    					public void onClick(View v) {
    						Toast.makeText(mContext,"单列," + (position - 1) + "", 0).show();
    					}
    				});
    			}
    		}
    	}
    
    	@Override
    	public MyRecycleAdapterHolder onCreateViewHolder(ViewGroup parent,
    			int viewType) {
    		View root = null;
    		// 头部
    		if (viewType == RecycleViewWithHead.HEADER_RECYCLER_VIEW_ITEM) {
    			root = headView;
    		} else {// 普通条目
    			/** 一行显示一条 */
    			if (viewType == RecycleViewWithHead.RECYCLER_VIEW_ITEM_SINGLE) {
    				root = LayoutInflater.from(mContext).inflate(R.layout.item_single, parent, false);
    			}
    			/** 一行显示两条 */
    			else {
    				root = LayoutInflater.from(mContext).inflate(R.layout.item_double, parent, false);
    			}
    		}
    		return new MyRecycleAdapterHolder(root, viewType);
    	}
    
    	/**
    	 * 加入自己定义头部
    	 */
    	public void addHeadView(View view) {
    		this.headView = view;
    	}
    
    	@Override
    	public int getItemViewType(int position) {
    
    		if (position == 0) {
    			return RecycleViewWithHead.HEADER_RECYCLER_VIEW_ITEM;
    		} else {
    			/** 一行显示一条 */
    			if (spanSize == RecycleViewWithHead.RECYCLER_VIEW_ITEM_SINGLE) {
    				return RecycleViewWithHead.RECYCLER_VIEW_ITEM_SINGLE;
    				/** 一行显示两条 */
    			} else {
    				return RecycleViewWithHead.RECYCLER_VIEW_ITEM_DOUBLE;
    			}
    		}
    	}
    
    	public int getSpanSize() {
    		return spanSize;
    	}
    
    	public void setSpanSize(int spanSize) {
    		this.spanSize = spanSize;
    	}
    }
    


    普通条目的ViewHolder

    import com.example.myrecycleviewdemo.R;
    import com.example.myrecycleviewdemo.R.id;
    import com.example.myrecycleviewdemo.RecycleViewWithHead;
    import android.support.v7.widget.RecyclerView;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    public class MyRecycleAdapterHolder extends RecyclerView.ViewHolder{
    	//一行两列视图
    	public ImageView iv_item_icon;
    	public TextView tv_item;
    	
    	//一行一列视图
    	public ImageView iv_item_icon_single;
    	public TextView tv_item_single;
    	
    	public MyRecycleAdapterHolder(View itemView) {
    		super(itemView);
    	}
    	public MyRecycleAdapterHolder(View itemView,int viewType) {
    		super(itemView);
    		initView(itemView,viewType);
    	}
    	private void initView(View itemView, int viewType) {
    		if(viewType == RecycleViewWithHead.RECYCLER_VIEW_ITEM_DOUBLE){
    			iv_item_icon = (ImageView) itemView.findViewById(R.id.iv_item_icon);
    			tv_item = (TextView) itemView.findViewById(R.id.tv_item);
    		}else if(viewType == RecycleViewWithHead.RECYCLER_VIEW_ITEM_SINGLE){
    			iv_item_icon_single = (ImageView) itemView.findViewById(R.id.iv_item_icon_single);
    			tv_item_single = (TextView) itemView.findViewById(R.id.tv_item_single);
    		}
    	}
    }
    

    头布局文件head.xm没有不论什么变化

    条目的布局拆分为2个item_double.xml和item_single.xml

    item_double.xml和之前的item.xml一样。


    item_single.xml

    <?

    xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/ll_list" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="2dp" android:layout_marginRight="2dp" android:layout_marginTop="5dp" android:orientation="horizontal" > <ImageView android:id="@+id/iv_item_icon_single" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/item" /> <TextView android:id="@+id/tv_item_single" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginTop="5dp" android:text="这是一仅仅熊猫" /> </LinearLayout>



    源代码地址:http://download.csdn.net/detail/linder_qzy/9491370



  • 相关阅读:
    事务隔离级别
    OpenSessionInView
    图像平滑处理(滤波)
    [原]Nginx+Lua服务端合并静态文件
    检查数据倾斜分布
    SQL Server研究之统计信息—发现过期统计信息并处理具体解释
    GDALWarp设置GDALWarpOptions::dfWarpMemoryLimit过大时处理失败
    Android Studio 2.0 稳定版新特性介绍
    供应商和管理员查看供应商地址簿信息SQL
    Table AdvanceTable针对表内行禁用multipleSelection , singleSelection
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/7220821.html
Copyright © 2011-2022 走看看