您好,登錄后才能下訂單哦!
Android中怎么使用RecyclerView控件實(shí)現(xiàn)混排效果,相信很多沒有經(jīng)驗(yàn)的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
項(xiàng)目結(jié)構(gòu)
引入依賴
首先是在Gradle中引入對RecyclerView的依賴
compile 'com.android.support:recyclerview-v7:25.3.1'
View包
由于項(xiàng)目用到的圖片是有規(guī)格限定的,所以需要對ImageView覆寫,得到我們想要尺寸的圖片
SquareImageView:正方形圖片
RectImageView:長方形圖片
public class SquareImageView extends android.support.v7.widget.AppCompatImageView { public SquareImageView(Context context) { this(context,null); } public SquareImageView(Context context, @Nullable AttributeSet attrs) { this(context, attrs,0); } public SquareImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setScaleType(ScaleType.FIT_XY); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, widthMeasureSpec); } }
public class RectImageView extends android.support.v7.widget.AppCompatImageView { public RectImageView(Context context) { this(context, null); } public RectImageView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public RectImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setScaleType(ScaleType.FIT_XY); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); // 設(shè)置大小為寬度的三分之二 int halfWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width / 3 * 2, widthMode); super.onMeasure(widthMeasureSpec, halfWidthMeasureSpec); } }
Music包
這里是我們存儲實(shí)體的地方,其中四種類型的劃分,分別對應(yīng)項(xiàng)目展示中的前三個模塊的劃分,其中還有一個標(biāo)題也算是一種類型,所以共四種
public class Music { public int type; public String title; // 后期可加入Glide加載網(wǎng)絡(luò)圖片Url public int imageId; public interface TYPE { int TYPE_GRID_THREE = 0x01; int TYPE_GRID_TWO = 0x02; int TYPE_LIST = 0x03; int TYPE_TITLE = 0x04; } }
Listener包
由于RecyclerView自身是沒有點(diǎn)擊事件的,所以這個包是RecyclerView的點(diǎn)擊事件接口
public interface OnItemClickListener { void OnItemClick(int position); }
Decoration包
由于RecyclerView是不提供分割線的,所以這個包是自定義的分割線
public class SpacesItemDecoration extends RecyclerView.ItemDecoration { private int space; public SpacesItemDecoration(int space) { this.space = space; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { outRect.left = space; outRect.right = space; outRect.bottom = space; outRect.top = space; } }
ViewHolder
這里存儲的是我們混排效果的控件,標(biāo)題可能會有點(diǎn)區(qū)別,其他是一樣的效果,為了后期方便拓展,我們就把他們分開,不代碼復(fù)用
public class GridThreeViewHolder extends RecyclerView.ViewHolder { public SquareImageView iv_icon; public TextView tv_content; public GridThreeViewHolder(View itemView) { super(itemView); iv_icon = (SquareImageView) itemView.findViewById(R.id.iv_icon); tv_content = (TextView) itemView.findViewById(R.id.tv_content); } }
public class GridTwoViewHolder extends RecyclerView.ViewHolder { public RectImageView iv_icon; public TextView tv_content; public GridTwoViewHolder(View itemView) { super(itemView); iv_icon = (RectImageView) itemView.findViewById(R.id.iv_icon); tv_content = (TextView) itemView.findViewById(R.id.tv_content); } }
public class ListViewHolder extends RecyclerView.ViewHolder { public RectImageView iv_icon; public TextView tv_content; public ListViewHolder(View itemView) { super(itemView); iv_icon = (RectImageView) itemView.findViewById(R.id.iv_icon); tv_content = (TextView) itemView.findViewById(R.id.tv_content); } }
public class TitleViewHolder extends RecyclerView.ViewHolder { public TextView tv_content; public TitleViewHolder(View itemView) { super(itemView); tv_content = (TextView) itemView.findViewById(R.id.tv_content); } }
Adapter包
這里就是對所有ViewHolder的控制器,然而這里并不是混排效果實(shí)現(xiàn)的最終地方,只不過是填充數(shù)據(jù)的地方
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements View.OnClickListener { private List<Music> mList; private Context mContext; private LayoutInflater mInflater; /** * 點(diǎn)擊事件 */ private OnItemClickListener mOnItemClickListener; public void setOnItemClickListener(OnItemClickListener onItemClickListener) { this.mOnItemClickListener = onItemClickListener; } public RecyclerAdapter(Context context, List<Music> list) { this.mList = list; this.mContext = context; this.mInflater = LayoutInflater.from(context); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view; RecyclerView.ViewHolder mViewHolder = null; if (viewType == Music.TYPE.TYPE_GRID_THREE) { view = mInflater.inflate(R.layout.item_grid_three, parent, false); mViewHolder = new GridThreeViewHolder(view); } else if (viewType == Music.TYPE.TYPE_GRID_TWO) { view = mInflater.inflate(R.layout.item_grid_two, parent, false); mViewHolder = new GridTwoViewHolder(view); } else if (viewType == Music.TYPE.TYPE_LIST) { view = mInflater.inflate(R.layout.item_list, parent, false); mViewHolder = new ListViewHolder(view); } else if (viewType == Music.TYPE.TYPE_TITLE) { view = mInflater.inflate(R.layout.item_title, parent, false); mViewHolder = new TitleViewHolder(view); } return mViewHolder; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { switch (getItemViewType(position)) { case Music.TYPE.TYPE_GRID_THREE: GridThreeViewHolder gHolder_three = (GridThreeViewHolder) holder; gHolder_three.tv_content.setText(mList.get(position).title); gHolder_three.iv_icon.setImageResource(mList.get(position).imageId); //點(diǎn)擊事件 gHolder_three.itemView.setOnClickListener(this); gHolder_three.itemView.setTag(position); break; case Music.TYPE.TYPE_GRID_TWO: GridTwoViewHolder gHolder_two = (GridTwoViewHolder) holder; gHolder_two.tv_content.setText(mList.get(position).title); gHolder_two.iv_icon.setImageResource(mList.get(position).imageId); //點(diǎn)擊事件 gHolder_two.itemView.setOnClickListener(this); gHolder_two.itemView.setTag(position); break; case Music.TYPE.TYPE_LIST: ListViewHolder lHolder = (ListViewHolder) holder; lHolder.tv_content.setText(mList.get(position).title); lHolder.iv_icon.setImageResource(mList.get(position).imageId); //點(diǎn)擊事件 lHolder.itemView.setOnClickListener(this); lHolder.itemView.setTag(position); break; case Music.TYPE.TYPE_TITLE: TitleViewHolder tHolder = (TitleViewHolder) holder; tHolder.tv_content.setText(mList.get(position).title); //點(diǎn)擊事件 tHolder.itemView.setOnClickListener(this); tHolder.itemView.setTag(position); break; } } @Override public int getItemViewType(int position) { return mList.get(position).type; } @Override public int getItemCount() { return mList.size(); } @Override public void onClick(View v) { if (mOnItemClickListener != null) { int position = (int) v.getTag(); mOnItemClickListener.OnItemClick(position); } } }
Activity
這里就是我們實(shí)現(xiàn)混排效果的關(guān)鍵,我們會根據(jù)不同類型的數(shù)據(jù),對RecyclerView的SpanSize的進(jìn)行設(shè)置
public class MainActivity extends AppCompatActivity implements OnItemClickListener { private RecyclerView ry; private GridLayoutManager layoutManager; private RecyclerAdapter mAdapter; private static List<Music> mList; /** * 模擬本地?cái)?shù)據(jù) */ static { mList = new ArrayList<>(); for (int i = 0; i < 1; i++) { Music music = new Music(); music.type = Music.TYPE.TYPE_TITLE; music.imageId = R.drawable.ic_cover; music.title = "推薦歌單"; mList.add(music); } for (int i = 0; i < 6; i++) { Music music = new Music(); music.type = Music.TYPE.TYPE_GRID_THREE; music.imageId = R.drawable.ic_cover; music.title = "先不要降溫!我沒錢買衣服"; mList.add(music); } for (int i = 0; i < 1; i++) { Music music = new Music(); music.type = Music.TYPE.TYPE_TITLE; music.imageId = R.drawable.ic_cover; music.title = "推薦MV"; mList.add(music); } for (int i = 0; i < 4; i++) { Music music = new Music(); music.type = Music.TYPE.TYPE_GRID_TWO; music.imageId = R.drawable.ic_cover; music.title = "Perfect Day"; mList.add(music); } for (int i = 0; i < 1; i++) { Music music = new Music(); music.type = Music.TYPE.TYPE_TITLE; music.imageId = R.drawable.ic_cover; music.title = "精選專欄"; mList.add(music); } for (int i = 0; i < 3; i++) { Music music = new Music(); music.type = Music.TYPE.TYPE_LIST; music.imageId = R.drawable.ic_cover; music.title = "去看《銀翼殺手2049》前,你應(yīng)該知道的三件事"; mList.add(music); } for (int i = 0; i < 1; i++) { Music music = new Music(); music.type = Music.TYPE.TYPE_TITLE; music.imageId = R.drawable.ic_cover; music.title = "最新音樂"; mList.add(music); } for (int i = 0; i < 6; i++) { Music music = new Music(); music.type = Music.TYPE.TYPE_GRID_THREE; music.imageId = R.drawable.ic_cover; music.title = "[BGM]一定聽過的神級背景配樂"; mList.add(music); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ry = (RecyclerView) findViewById(R.id.ry); layoutManager = new GridLayoutManager(this, 6); layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { int type = mList.get(position).type; if (type == Music.TYPE.TYPE_GRID_THREE) { return 2; } else if (type == Music.TYPE.TYPE_GRID_TWO) { return 3; } else if (type == Music.TYPE.TYPE_LIST) { return 6; } else if (type == Music.TYPE.TYPE_TITLE) { return 6; } return 0; } }); ry.setLayoutManager(layoutManager); ry.addItemDecoration(new SpacesItemDecoration(2)); // 填充數(shù)據(jù) mAdapter = new RecyclerAdapter(this, mList); mAdapter.setOnItemClickListener(this); ry.setAdapter(mAdapter); } @Override public void OnItemClick(int position) { String title = mList.get(position).title; Toast.makeText(this, title, Toast.LENGTH_SHORT).show(); } }
看完上述內(nèi)容,你們掌握Android中怎么使用RecyclerView控件實(shí)現(xiàn)混排效果的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。