国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android控件RecyclerView實現混排效果仿網易云音樂

2019-10-22 18:24:41
字體:
來源:轉載
供稿:網友

前言

最近在使用網易云音樂的時候,看到如下圖的排版效果圖,自己也想實現一個

Android,RecyclerView,混排

這里采用網上用法最多的方式,而且是比較簡單的方式實現的,想要做項目的同學也可以快速入手搞定首頁界面,可以在最快的時間內模仿出來,且效果達到90%以上的相似

效果演示

至于圖片的加載你們可以根據網上的Api獲取相應的圖片加載到對應的位置,這里只是采用本地圖片來演示

Android,RecyclerView,混排

實現分析

這里是采用RecyclerView的GridLayoutManager的一個SpanSize這么一個東西,從下圖很容易知道其意思

Android,RecyclerView,混排

項目結構

項目結構可能對初學者感覺很龐大,不用擔心,這里我會按照下面的包名劃分,從最簡單的開始分析

Android,RecyclerView,混排

引入依賴

首先是在Gradle中引入對RecyclerView的依賴

compile 'com.android.support:recyclerview-v7:25.3.1'

View包

由于項目用到的圖片是有規格限定的,所以需要對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);    // 設置大小為寬度的三分之二    int halfWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width / 3 * 2, widthMode);    super.onMeasure(widthMeasureSpec, halfWidthMeasureSpec);  }}

Music包

這里是我們存儲實體的地方,其中四種類型的劃分,分別對應項目展示中的前三個模塊的劃分,其中還有一個標題也算是一種類型,所以共四種

public class Music {  public int type;  public String title;  // 后期可加入Glide加載網絡圖片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自身是沒有點擊事件的,所以這個包是RecyclerView的點擊事件接口

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

這里存儲的是我們混排效果的控件,標題可能會有點區別,其他是一樣的效果,為了后期方便拓展,我們就把他們分開,不代碼復用

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的控制器,然而這里并不是混排效果實現的最終地方,只不過是填充數據的地方

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements View.OnClickListener {  private List<Music> mList;  private Context mContext;  private LayoutInflater mInflater;  /**   * 點擊事件   */  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);        //點擊事件        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);        //點擊事件        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);        //點擊事件        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);        //點擊事件        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

這里就是我們實現混排效果的關鍵,我們會根據不同類型的數據,對RecyclerView的SpanSize的進行設置

public class MainActivity extends AppCompatActivity implements OnItemClickListener {  private RecyclerView ry;  private GridLayoutManager layoutManager;  private RecyclerAdapter mAdapter;  private static List<Music> mList;  /**   * 模擬本地數據   */  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》前,你應該知道的三件事";      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));    // 填充數據    mAdapter = new RecyclerAdapter(this, mList);    mAdapter.setOnItemClickListener(this);    ry.setAdapter(mAdapter);  }  @Override  public void OnItemClick(int position) {    String    Toast.makeText(this, title, Toast.LENGTH_SHORT).show();  }}

layout布局文件

這里的布局很簡單,比如用到我們的正方形圖片,長方形圖片等,這里就不做代碼貼出,詳細可以查看源碼

源碼下載

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 灵丘县| 达孜县| 新蔡县| 得荣县| 黑河市| 四子王旗| 剑河县| 菏泽市| 平湖市| 安陆市| 元朗区| 乡宁县| 七台河市| 大关县| 山西省| 台中县| 繁峙县| 巴彦淖尔市| 获嘉县| 漳浦县| 克什克腾旗| 信阳市| 锡林郭勒盟| 马公市| 罗定市| 多伦县| 佛山市| 克山县| 田林县| 舞阳县| 淳化县| 嘉义县| 奎屯市| 依安县| 乌兰浩特市| 洛宁县| 昂仁县| 尉氏县| 靖西县| 施秉县| 札达县|