日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android view.settran,Android RecyclerView从入门到玩坏

發布時間:2025/3/11 Android 61 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android view.settran,Android RecyclerView从入门到玩坏 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

前言

基礎使用

分隔線

點擊監聽

搭配CardView

更豐富的條目

增刪條目

快速添加視圖

讓RecyclerView支持復雜視圖

最后前言

RecyclerView在Android界面開發當中是很重要的, 那掌握它也是很必要的. 但是有些時候會覺得它很厚重, 這里就從RecyclerView的基礎一直說到擴展, 讓你把RecyclerView學薄了.

這篇文章融合了自己原來的多篇文章, 并進行了修正和改進, 而且添加了很多很有趣的內容.

本文需要20分鐘以上的閱讀時間, 請合理安排.

多圖預警, 轉載請注明出處!

基礎使用

要使用RecyclerView在Android Studio 2.x(以下簡稱AS), 要這樣:

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

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

到了AS 3.x, 要這樣:

implementation 'com.android.support:cardview-v7:26.1.0'

implementation 'com.android.support:recyclerview-v7:26.1.0'

之后在布局文件中寫入如下代碼就引入了RecyclerView了.

android:id="@+id/rv_main"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:scrollbars="vertical" />

布局類

效果LinearLayoutManager

以垂直或水平滾動列表方式顯示項目

GridLayoutManager

在網格中顯示項目

StaggeredGridLayoutManager

在分散對齊網格中顯示項目mRvMain = (RecyclerView) findViewById(R.id.rv_main);

// 設置布局

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);

mRvMain.setLayoutManager(linearLayoutManager);

最關鍵的還是適配器的撰寫. 但是理解起來不是很難, 你只要將ListView的適配器寫法帶入理解就好. 這里把全部代碼貼出來, 因為后面要在這個基礎上不斷擴充.

public class MyRVAdapter2 extends RecyclerView.Adapter {

private final LayoutInflater mLayoutInflater;

private final Context mContext;

private final ArrayList mData;

public MyRVAdapter2(Context context) {

mLayoutInflater = LayoutInflater.from(context);

mContext = context;

mData = new ArrayList<>();

for (int i = 0; i < 40; i++) {

mData.add("hello " + i);

}

}

@Override

public MyRVAdapter2.MyTVHolder onCreateViewHolder(ViewGroup parent, int viewType) {

return new MyRVAdapter2.MyTVHolder(mLayoutInflater.inflate(R.layout.rv_txt_item, parent, false));

}

@Override

public void onBindViewHolder(final MyRVAdapter2.MyTVHolder holder, int pos) {

holder.mTextView.setText(mData.get(pos));

}

@Override

public int getItemCount() {

return mData == null ? 0 : mData.size();

}

class MyTVHolder extends RecyclerView.ViewHolder {

TextView mTextView;

MyTVHolder(View itemView) {

super(itemView);

mTextView = (TextView) itemView.findViewById(R.id.tv_txt);

}

}

}

然后寫個最基礎的TextView條目. 讓它跑起來看看效果.

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal">

android:id="@+id/tv_txt"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:gravity="center_horizontal"

android:padding="@dimen/eight_dp"

android:text="@string/tmp"

android:textSize="@dimen/thirty_sp" />

分隔線

前面的部分已經是基礎的RecyclerView使用了. 那比起ListView是不是沒有了分隔線. 這里上一個簡單好用的開源庫RecyclerView-FlexibleDivider.

引入:

implementation 'com.yqritc:recyclerview-flexibledivider:1.4.0'

使用:

mRvMain.addItemDecoration(

new HorizontalDividerItemDecoration.Builder(this).build());

看效果就達到了吧.

覺得不好看, 還可以自定義, 更多寫法可以參見文檔內容.

mRvMain.addItemDecoration(

new HorizontalDividerItemDecoration.Builder(this)

.color(Color.BLUE)

.sizeResId(R.dimen.two_dp)

.marginResId(R.dimen.eight_dp, R.dimen.eight_dp)

.build());

而且而且, 豎著的分隔線也大丈夫哦.

GridLayoutManager gridLayoutManager

= new GridLayoutManager(this, 2);

mRvMain.setLayoutManager(gridLayoutManager);

mRvMain.addItemDecoration(

new VerticalDividerItemDecoration.Builder(this).build());

點擊監聽

再回憶一下在天國的ListView, 還有item的點擊吧, 這個也要自己寫.

適配器中:

public interface OnItemClickListener {

void onItemClick(View view, int position);

void onItemLongClick(View view, int position);

}

private MyRVAdapter2.OnItemClickListener mOnItemClickListener;

public void setOnItemClickListener(MyRVAdapter2.OnItemClickListener mOnItemClickListener) {

this.mOnItemClickListener = mOnItemClickListener;

}

onBindViewHolder中設置點擊監聽.

@Override

public void onBindViewHolder(final MyRVAdapter2.MyTVHolder holder, int pos) {

holder.mTextView.setText(mData.get(pos));

if (mOnItemClickListener != null) {

holder.itemView.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

int pos = holder.getLayoutPosition();

mOnItemClickListener.onItemClick(holder.itemView, pos);

}

});

holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {

@Override

public boolean onLongClick(View v) {

int pos = holder.getLayoutPosition();

mOnItemClickListener.onItemLongClick(holder.itemView, pos);

return false;

}

});

}

}

使用監聽:

mAdapter.setOnItemClickListener(new MyRVAdapter2.OnItemClickListener() {

@Override

public void onItemClick(View view, int position) {

Toast.makeText(UIUtil.getContext(), "click" + position, Toast.LENGTH_SHORT).show();

}

@Override

public void onItemLongClick(View view, int position) {

Toast.makeText(UIUtil.getContext(), "long click" + position, Toast.LENGTH_SHORT).show();

}

});

搭配CardView

是不是這個點擊看著沒啥感覺, 沒事, 我們換上CardView再來一次.

布局文件:

xmlns:card_view="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_margin="@dimen/eight_dp"

android:foreground="@drawable/card_foreground"

card_view:cardCornerRadius="@dimen/four_dp">

android:id="@+id/tv_txt"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:gravity="center_horizontal"

android:padding="@dimen/eight_dp"

android:text="@string/tmp"

android:textSize="@dimen/thirty_sp" />

給CardView加上水波紋點擊特效:

android:color="@color/colorPrimary" />

在老版本就只能用選擇器了, 其實效果也還好:

android:drawable="@drawable/card_foreground_selector"

android:insetBottom="@dimen/four_dp"

android:insetLeft="@dimen/three_dp"

android:insetRight="@dimen/three_dp"

android:insetTop="@dimen/four_dp" />

更豐富的條目

大家應該都知道TextView可以設置圖標吧, 這里來看下效果圖, 順帶感受下android界面設計語言的變化.

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal">

android:id="@+id/tv_txt"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:drawableLeft="@mipmap/ic_launcher"

android:drawablePadding="@dimen/sixteen_dp"

android:drawableStart="@mipmap/ic_launcher"

android:gravity="center_vertical"

android:padding="@dimen/eight_dp"

android:text="@string/tmp"

android:textSize="@dimen/thirty_sp" />

讓GridLayoutManager展示不同寬度的條目

方的是4.x上的, 圓的是8.x上的, 可以看到, 變化還是很大的. 我們回正題. GridLayoutManager布局是可以設置寬度的, 不一定都是一樣大的, 來看下實現.

// 指定item寬度

gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {

@Override

public int getSpanSize(int position) {

if (position == 0

|| position == (mAdapter.getItemCount() - 1) / 2

|| position == (mAdapter.getItemCount() - 1)) {

return gridLayoutManager.getSpanCount();

} else {

return 1;

}

}

});

來看效果圖, 發現我們的分隔線崩了是吧, 如果真想用這個分隔線也還是要自己動手修補修補, 改動改動, 開源庫再棒也猜不到你的項目需求呀.

當然了, 我還是很喜歡這個分隔線的, 我們來看看橫著滾動的效果.

布局文件要改動:

android:layout_width="wrap_content"

android:layout_height="match_parent"

android:orientation="horizontal">

android:id="@+id/tv_txt"

android:layout_width="wrap_content"

android:layout_height="match_parent"

android:gravity="center_vertical"

android:text="@string/tmp"

android:textSize="@dimen/thirty_sp" />

gridLayoutManager.setOrientation(GridLayoutManager.HORIZONTAL);

展示不同布局

之前變化寬度其實還是相同條目, 現在要展示不同條目:

寫一個圖的條目:

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:padding="@dimen/eight_dp">

android:id="@+id/iv_img"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:class="lazyload" src="https://img-blog.csdnimg.cn/2022010702381440793.png" data-original="@mipmap/ic_launcher" />

public enum ITEM_TYPE {

ITEM_TYPE_IMAGE,

ITEM_TYPE_TEXT

}

這里多了判斷條目類型, 還要注意返回值的變化, 用了更基類的RecyclerView.ViewHolder.

@Override

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

if (viewType == ITEM_TYPE.ITEM_TYPE_IMAGE.ordinal()) {

return new MyRVAdapter2.MyIVHolder(mLayoutInflater.inflate(R.layout.rv_img_item, parent, false));

} else {

return new MyRVAdapter2.MyTVHolder(mLayoutInflater.inflate(R.layout.rv_txt_item, parent, false));

}

}

類繼承上面也要變成RecyclerView.ViewHolder, 這些都是要對應的.

extends RecyclerView.Adapter

當然了, holder也是不能少的.

public class MyIVHolder extends RecyclerView.ViewHolder {

ImageView mImageView;

MyIVHolder(View view) {

super(view);

mImageView = (ImageView) view.findViewById(R.id.iv_img);

}

}

@Override

public void onBindViewHolder(final RecyclerView.ViewHolder holder, int pos) {

if (holder instanceof MyRVAdapter2.MyTVHolder) {

((MyRVAdapter2.MyTVHolder) holder).mTextView.setText(mData.get(pos));

} else if (holder instanceof MyRVAdapter2.MyIVHolder) {

((MyRVAdapter2.MyIVHolder) holder).mImageView.setImageDrawable(UIUtil.getDrawable(R.mipmap.ic_launcher));

}

// 點擊監聽

...

}

順帶的, 我們把之前放寬的條目變成不同的視圖, 也就是對應起來:

@Override

public int getItemViewType(int position) {

if (position == 0

|| position == (getItemCount() - 1) / 2

|| position == (getItemCount() - 1)) {

return ITEM_TYPE.ITEM_TYPE_IMAGE.ordinal();

} else {

return ITEM_TYPE.ITEM_TYPE_TEXT.ordinal();

}

}

看看效果:

它還能繼續地復雜, 試試瀑布流StaggeredGridLayoutManager:

xmlns:card_view="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_margin="@dimen/eight_dp"

card_view:cardCornerRadius="@dimen/four_dp">

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="vertical">

android:id="@+id/iv_img"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"

android:class="lazyload" src="https://img-blog.csdnimg.cn/2022010702381440793.png" data-original="@mipmap/ic_launcher" />

android:id="@+id/tv_txt"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"

android:text="@string/tmp"

android:textSize="@dimen/thirty_sp" />

StaggeredGridLayoutManager staggeredGridLayoutManager

= new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);

mRvMain.setLayoutManager(staggeredGridLayoutManager);

分割線又崩了, 嘿嘿, 其實用上了CardView, 分割線沒什么必要再用了.

增刪條目

現在適配器中添加增刪方法:

public void addData(int position) {

mData.add(position, "hello x");

notifyItemInserted(position);

}

public void removeData(int position) {

mData.remove(position);

notifyItemRemoved(position);

}

再寫入點擊事件中, 點擊增加, 長按刪除:

mAdapter.setOnItemClickListener(new MyRVAdapter2.OnItemClickListener() {

@Override

public void onItemClick(View view, int position) {

mAdapter.addData(position);

}

@Override

public void onItemLongClick(View view, int position) {

mAdapter.removeData(position);

}

});

增刪條目開源庫

這里再上一個開源庫recyclerview-animators, 可以修改增刪動畫, 種類也很豐富, 還能在它基礎上自定義:

分類

動畫類名Cool

LandingAnimator

Scale

ScaleInAnimator, ScaleInTopAnimator, ScaleInBottomAnimator, ScaleInLeftAnimator, ScaleInRightAnimator

Fade

FadeInAnimator, FadeInDownAnimator, FadeInUpAnimator, FadeInLeftAnimator, FadeInRightAnimator

Flip

FlipInTopXAnimator, FlipInBottomXAnimator, FlipInLeftYAnimator, FlipInRightYAnimator

Slide

SlideInLeftAnimator, SlideInRightAnimator, OvershootInLeftAnimator, OvershootInRightAnimator, SlideInUpAnimator, SlideInDownAnimator引入:

implementation 'jp.wasabeef:recyclerview-animators:2.3.0'

使用:

mRvMain.setItemAnimator(new SlideInLeftAnimator());

這里給大家展示兩種效果, 其它的自己嘗試吧.

mRvMain.setItemAnimator(new LandingAnimator());

快速添加視圖

還有像Header, Foot這樣的視圖, 自己寫也還是要費些功夫的, 這里推薦Android大神的庫baseAdapter

引入:

implementation 'com.zhy:base-rvadapter:3.0.3'

添加頭尾視圖

HeaderAndFooterWrapper mHeaderAndFooterWrapper = new HeaderAndFooterWrapper(mAdapter);

TextView t1 = new TextView(this);

t1.setText("Header 1");

t1.setTextSize(30);

TextView t2 = new TextView(this);

t2.setText("Foot 1");

t2.setTextSize(30);

mHeaderAndFooterWrapper.addHeaderView(t1);

mHeaderAndFooterWrapper.addFootView(t2);

mRvMain.setAdapter(mHeaderAndFooterWrapper);

添加更多視圖

LoadMoreWrapper mLoadMoreWrapper = new LoadMoreWrapper(mAdapter);

mLoadMoreWrapper.setLoadMoreView(R.layout.rv_cv_img_txt_item);

mLoadMoreWrapper.setOnLoadMoreListener(new LoadMoreWrapper.OnLoadMoreListener() {

@Override

public void onLoadMoreRequested() {

}

});

mRvMain.setAdapter(mLoadMoreWrapper);

是不是感覺特別爽, 那看看更爽的, 在不寫適配器的情況下快速添加條目:

final ArrayList mData = new ArrayList<>();

for (int i = 0; i < 40; i++) {

mData.add("hello " + i);

}

mRvMain.setAdapter(new CommonAdapter(this, R.layout.rv_cv_txt_item, mData) {

@Override

protected void convert(ViewHolder holder, String s, int position) {

holder.setText(R.id.tv_txt, mData.get(position));

}

});

是不是感覺省了一萬個小時呢.

讓RecyclerView支持復雜視圖

每次加入新的視圖都要對適配器進行比較大程度的改動, 這樣是很容易出錯的. 這里引入一個非常棒的開源庫-AdapterDelegates, 降低下代碼耦合性.

引入:

implementation 'com.hannesdorfmann:adapterdelegates3:3.0.1'

先不說使用細節, 來看看實現后想加入不同視圖有多簡單吧:

ArrayList data = new ArrayList<>();

for (int i = 0; i < 10; i++) {

data.add(new B("b " + i));

}

for (int i = 0; i < 10; i++) {

data.add(new A("a " + i));

}

BaseAdapter animalAdapter = new BaseAdapter(this, data);

mRvMain.setAdapter(animalAdapter);

是不是驚了, 也就是說, 你只要實現了A, B這些視圖類, 直接新建放入數組就完事了.

需要寫基礎適配器:

public class BaseAdapter extends RecyclerView.Adapter {

private AdapterDelegatesManager> delegatesManager;

private List items;

public BaseAdapter(Activity activity, List items) {

this.items = items;

delegatesManager = new AdapterDelegatesManager<>();

delegatesManager.addDelegate(new AAdapterDelegate(activity))

.addDelegate(new BAdapterDelegate(activity));

}

@Override

public int getItemViewType(int position) {

return delegatesManager.getItemViewType(items, position);

}

@Override

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

return delegatesManager.onCreateViewHolder(parent, viewType);

}

@Override

public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

delegatesManager.onBindViewHolder(items, position, holder);

}

@Override

public int getItemCount() {

return items.size();

}

}

需要對每個類進行進行具體設置, 這里以A為例.

public class AAdapterDelegate extends AdapterDelegate> {

private LayoutInflater inflater;

public AAdapterDelegate(Activity activity) {

inflater = activity.getLayoutInflater();

}

@Override

public boolean isForViewType(@NonNull List items, int position) {

return items.get(position) instanceof A;

}

@NonNull

@Override

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent) {

return new CatViewHolder(inflater.inflate(R.layout.rv_cv_img_txt_item, parent, false));

}

@Override

public void onBindViewHolder(@NonNull List items, int position,

@NonNull RecyclerView.ViewHolder holder, @Nullable List payloads) {

CatViewHolder vh = (CatViewHolder) holder;

A cat = (A) items.get(position);

vh.name.setText(cat.getName());

}

static class CatViewHolder extends RecyclerView.ViewHolder {

public TextView name;

public ImageView img;

public CatViewHolder(View itemView) {

super(itemView);

name = (TextView) itemView.findViewById(R.id.tv_txt);

img = (ImageView) itemView.findViewById(R.id.iv_img);

}

}

}

最后

看完這篇應該是對RecyclerView有個大體認識了, 多練習練習就會得心應手起來了. 那還是有一點, 就像分隔線庫的幾次不理想表現, 具體項目要求還是要具體對待, 開源庫也不是萬能的. 最近不是又有什么開源項目套殼事件了嘛, 別人一開源就說自己有自主產權了真的好嗎? 喜歡記得點贊或者關注我哦, 有意見或者建議評論區見~

總結

以上是生活随笔為你收集整理的Android view.settran,Android RecyclerView从入门到玩坏的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。