RecyclerView使用詳解
RecylerView介紹
RecylerView是support-v7包中的新組件,是一個(gè)強(qiáng)大的滑動(dòng)組件,與經(jīng)典的ListView相比,同樣擁有item回收復(fù)用的功能,這一點(diǎn)從它的名字recylerview即回收view也可以看出。官方對(duì)于它的介紹則是:RecyclerView 是 ListView 的升級(jí)版本,更加先進(jìn)和靈活。RecyclerView通過設(shè)置LayoutManager,ItemDecoration,ItemAnimator實(shí)現(xiàn)你想要的效果。
- 使用LayoutManager來確定每一個(gè)item的排列方式。
- 使用ItemDecoration自己繪制分割線,更靈活
- 使用ItemAnimator為增加或刪除一行設(shè)置動(dòng)畫效果。
注意
新建完項(xiàng)目,需要在app/build.gradle增加RecylerView依賴,不然找不到RecyclerView類
compile 'com.android.support:recyclerview-v7:23.1.0'
RecylerView簡單的Demo
我們來看activity代碼,跟ListView寫法差不多,只是這邊多設(shè)置了布局管理器。
public class LinearLayoutActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private RecyclerViewAdapter adapter;
private List<String> datas;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recycler_main);
initData();
recyclerView= (RecyclerView) findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));//設(shè)置布局管理器
recyclerView.addItemDecoration(new DividerItemDecoration(this));
recyclerView.setAdapter(adapter=new RecyclerViewAdapter(this,datas));
}
private void initData(){
datas=new ArrayList<>();
for(int i=0;i<100;i++){
datas.add("item:"+i);
}
}
}
activity對(duì)應(yīng)的布局文件:recycler_main.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"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
adapter相對(duì)ListView來說變化比較大的。把ViewHolder邏輯封裝起來了,代碼相對(duì)簡單一些。
- 需要繼承RecyclerView.Adapter,重寫三個(gè)方法
- MyViewHolder需要繼承RecyclerView.ViewHolder
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder>{
private List<String> datas;
private LayoutInflater inflater;
public RecyclerViewAdapter(Context context,List<String> datas){
inflater=LayoutInflater.from(context);
this.datas=datas;
}
//創(chuàng)建每一行的View 用RecyclerView.ViewHolder包裝
@Override
public RecyclerViewAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView=inflater.inflate(R.layout.recycler_item,null);
return new MyViewHolder(itemView);
}
//給每一行View填充數(shù)據(jù)
@Override
public void onBindViewHolder(RecyclerViewAdapter.MyViewHolder holder, int position) {
holder.textview.setText(datas.get(position));
}
//數(shù)據(jù)源的數(shù)量
@Override
public int getItemCount() {
return datas.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
private TextView textview;
public MyViewHolder(View itemView) {
super(itemView);
textview= (TextView) itemView.findViewById(R.id.textview);
}
}
}
我們來看看效果圖:

RecyclerView增加分隔線
RecyclerView是沒有android:divider跟android:dividerHeight屬性的,如果我們需要分割線,就只能自己動(dòng)手去實(shí)現(xiàn)了。
- 需要繼承ItemDecoration類,實(shí)現(xiàn)onDraw跟getItemOffsets方法。
- 調(diào)用RecyclerView的addItemDecoration方法。
我們先寫一個(gè)DividerItemDecoration類,繼承RecyclerView.ItemDecoration,在getItemOffsets留出item之間的間隔,然后就會(huì)調(diào)用onDraw方法繪制(onDraw的繪制優(yōu)先于每一行的繪制)
public class DividerItemDecoration extends RecyclerView.ItemDecoration{
/*
* RecyclerView的布局方向,默認(rèn)先賦值 為縱向布局
* RecyclerView 布局可橫向,也可縱向
* 橫向和縱向?qū)?yīng)的分割線畫法不一樣
* */
private int mOrientation = LinearLayoutManager.VERTICAL;
private int mItemSize = 1;//item之間分割線的size,默認(rèn)為1
private Paint mPaint;//繪制item分割線的畫筆,和設(shè)置其屬性
public DividerItemDecoration(Context context) {
this(context,LinearLayoutManager.VERTICAL,R.color.colorAccent);
}
public DividerItemDecoration(Context context, int orientation) {
this(context,orientation, R.color.colorAccent);
}
public DividerItemDecoration(Context context, int orientation, int dividerColor){
this(context,orientation,dividerColor,1);
}
/**
* @param context
* @param orientation 繪制方向
* @param dividerColor 分割線顏色 顏色資源id
* @param mItemSize 分割線寬度 傳入dp值就行
*/
public DividerItemDecoration(Context context, int orientation, int dividerColor, int mItemSize){
this.mOrientation = orientation;
if(orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL){
throw new IllegalArgumentException("請(qǐng)傳入正確的參數(shù)") ;
}
//把dp值換算成px
this.mItemSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,mItemSize,context.getResources().getDisplayMetrics());
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(context.getResources().getColor(dividerColor));
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
if(mOrientation == LinearLayoutManager.VERTICAL){
drawVertical(c,parent) ;
}else {
drawHorizontal(c,parent) ;
}
}
/**
* 繪制縱向 item 分割線
* @param canvas
* @param parent
*/
private void drawVertical(Canvas canvas,RecyclerView parent){
final int left = parent.getPaddingLeft() ;
final int right = parent.getMeasuredWidth() - parent.getPaddingRight();
final int childSize = parent.getChildCount() ;
for(int i = 0 ; i < childSize ; i ++){
final View child = parent.getChildAt( i ) ;
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
final int top = child.getBottom() + layoutParams.bottomMargin ;
final int bottom = top + mItemSize ;
canvas.drawRect(left,top,right,bottom,mPaint);
}
}
/**
* 繪制橫向 item 分割線
* @param canvas
* @param parent
*/
private void drawHorizontal(Canvas canvas,RecyclerView parent){
final int top = parent.getPaddingTop() ;
final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom() ;
final int childSize = parent.getChildCount() ;
for(int i = 0 ; i < childSize ; i ++){
final View child = parent.getChildAt( i ) ;
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getRight() + layoutParams.rightMargin ;
final int right = left + mItemSize ;
canvas.drawRect(left,top,right,bottom,mPaint);
}
}
/**
* 設(shè)置item分割線的size
* @param outRect
* @param view
* @param parent
* @param state
*/
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if(mOrientation == LinearLayoutManager.VERTICAL){
outRect.set(0,0,0,mItemSize);//垂直排列 底部偏移
}else {
outRect.set(0,0,mItemSize,0);//水平排列 右邊偏移
}
}
}
不要忘記調(diào)用addItemDecoration方法哦
recyclerView.addItemDecoration(new DividerItemDecoration(this));//添加分割線
重新運(yùn)行,效果圖:

大家讀到這里肯定會(huì)有一個(gè)疑問,這貨比ListView麻煩多了啊,但是google官方為什么要說是ListView的升級(jí)版呢?接下來開始放大招。。。
GridLayoutManager
在RecyclerView中實(shí)現(xiàn)不同的列表,只需要切換不同的LayoutManager即可。RecyclerView.LayoutManager跟RecyclerView.ItemDecoration一樣,都是RecyclerView靜態(tài)抽象內(nèi)部類,但是LayoutManager有三個(gè)官方寫好的實(shí)現(xiàn)類。
- LinearLayoutManager 線性布局管理器 跟ListView功能相似
- GridLayoutManager 網(wǎng)格布局管理器 跟GridView功能相似
- StaggeredGridLayoutManager 瀑布流布局管理器
剛剛我們用的是LinearLayoutManager,現(xiàn)在我們切換到GridLayoutManager,看到下面這句代碼,有沒有感覺分分鐘切換不同列表顯示。
recyclerView.setLayoutManager(new GridLayoutManager(this,2));
如果要顯示多列或者要縱向顯示就new不同的構(gòu)造方法,以下代碼縱向顯示4列。當(dāng)前如果你還需要反方向顯示,把false改成true就可以。
recyclerView.setLayoutManager(new GridLayoutManager(this,4,GridLayoutManager.HORIZONTAL,false));
因?yàn)橛玫氖蔷W(wǎng)格布局,所以呢繪制分割線的代碼需要重新修改一下。網(wǎng)格布局一行可以有多列,并且最后一列跟最后一行不需要繪制,所以我們得重新創(chuàng)建一個(gè)類。
DividerGridItemDecoration.java
public class DividerGridItemDecoration extends RecyclerView.ItemDecoration {
/*
* RecyclerView的布局方向,默認(rèn)先賦值 為縱向布局
* RecyclerView 布局可橫向,也可縱向
* 橫向和縱向?qū)?yīng)的分割線畫法不一樣
* */
private int mOrientation = LinearLayoutManager.VERTICAL;
private int mItemSize = 1;//item之間分割線的size,默認(rèn)為1
private Paint mPaint;//繪制item分割線的畫筆,和設(shè)置其屬性
public DividerGridItemDecoration(Context context) {
this(context,LinearLayoutManager.VERTICAL,R.color.colorAccent);
}
public DividerGridItemDecoration(Context context, int orientation) {
this(context,orientation, R.color.colorAccent);
}
public DividerGridItemDecoration(Context context, int orientation, int dividerColor){
this(context,orientation,dividerColor,1);
}
/**
* @param context
* @param orientation 繪制方向
* @param dividerColor 分割線顏色 顏色資源id
* @param mItemSize 分割線寬度 傳入dp值就行
*/
public DividerGridItemDecoration(Context context, int orientation, int dividerColor, int mItemSize){
this.mOrientation = orientation;
if(orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL){
throw new IllegalArgumentException("請(qǐng)傳入正確的參數(shù)") ;
}
//把dp值換算成px
this.mItemSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,mItemSize,context.getResources().getDisplayMetrics());
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(context.getResources().getColor(dividerColor));
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
drawHorizontal(c, parent);
drawVertical(c, parent);
}
private int getSpanCount(RecyclerView parent) {
// 列數(shù)
int spanCount = -1;
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
spanCount = ((StaggeredGridLayoutManager) layoutManager).getSpanCount();
}
return spanCount;
}
public void drawHorizontal(Canvas canvas, RecyclerView parent) {
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getLeft() - params.leftMargin;
final int right = child.getRight() + params.rightMargin + mItemSize;
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mItemSize;
canvas.drawRect(left,top,right,bottom,mPaint);
}
}
public void drawVertical(Canvas canvas, RecyclerView parent) {
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int top = child.getTop() - params.topMargin;
final int bottom = child.getBottom() + params.bottomMargin;
final int left = child.getRight() + params.rightMargin;
final int right = left + mItemSize;
canvas.drawRect(left,top,right,bottom,mPaint);
}
}
@Override
public void getItemOffsets(Rect outRect, int itemPosition,RecyclerView parent) {
int spanCount = getSpanCount(parent);
int childCount = parent.getAdapter().getItemCount();
if (isLastRow(parent, itemPosition, spanCount, childCount)){//如果是最后一行,不需要繪制底部
outRect.set(0, 0, mItemSize, 0);
} else if (isLastColum(parent, itemPosition, spanCount, childCount)){// 如果是最后一列,不需要繪制右邊
outRect.set(0, 0, 0, mItemSize);
} else {
outRect.set(0, 0, mItemSize,mItemSize);
}
}
private boolean isLastColum(RecyclerView parent, int pos, int spanCount, int childCount) {
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
if ((pos + 1) % spanCount == 0){// 如果是最后一列,則不需要繪制右邊
return true;
}
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
int orientation = ((StaggeredGridLayoutManager) layoutManager).getOrientation();
if (orientation == StaggeredGridLayoutManager.VERTICAL) {
if ((pos + 1) % spanCount == 0){// 如果是最后一列,則不需要繪制右邊
return true;
}
} else {
childCount = childCount - childCount % spanCount;
if (pos >= childCount)// 如果是最后一列,則不需要繪制右邊
return true;
}
}
return false;
}
private boolean isLastRow(RecyclerView parent, int pos, int spanCount, int childCount) {
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
childCount = childCount - childCount % spanCount;
if (pos >= childCount)//最后一行
return true;
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
int orientation = ((StaggeredGridLayoutManager) layoutManager).getOrientation();
if (orientation == StaggeredGridLayoutManager.VERTICAL){//縱向
childCount = childCount - childCount % spanCount;
if (pos >= childCount)//最后一行
return true;
} else{ //橫向
if ((pos + 1) % spanCount == 0) {//是最后一行
return true;
}
}
}
return false;
}
}
寫了這兩個(gè)畫分割線的類,主流的布局:線性列表跟網(wǎng)格列表都能展示了。。。趕緊運(yùn)行代碼看看結(jié)果:

StaggeredGridLayoutManager
actviity中修改下布局管理器,大家應(yīng)該感覺很熟悉了吧~~~
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL));
瀑布流列表一般列的高度是不一致的,為了模擬不同的寬高,數(shù)據(jù)源我把String類型改成了對(duì)象.然后初始化的時(shí)候隨機(jī)了一個(gè)高度.
public class ItemData {
private String content;//item內(nèi)容
private int height;//item高度
public ItemData() {
}
public ItemData(String content, int height) {
this.content = content;
this.height = height;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}
瀑布流列表沒有添加分割線,給item布局設(shè)置了android:padding屬性。recycler_staggered_item.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:padding="5dp" android:layout_width="wrap_content" android:layout_height="match_parent"> <TextView android:id="@+id/textview" android:background="@color/colorAccent" android:layout_width="100dp" android:layout_height="wrap_content" android:gravity="center" android:text="122" android:textSize="20sp"/> </FrameLayout>
最后我們?cè)谶m配器的onBindViewHolder方法中給itemd中的TextView設(shè)置一個(gè)高度
@Override
public void onBindViewHolder(StaggeredGridAdapter.MyViewHolder holder, int position) {
ItemData itemData=datas.get(position);
holder.textview.setText(itemData.getContent());
//手動(dòng)更改高度,不同位置的高度有所不同
holder.textview.setHeight(itemData.getHeight());
}
是不是感覺so easy,趕緊運(yùn)行看看效果:

添加header跟footer
RecyclerView添加頭部跟底部是沒有對(duì)應(yīng)的api的,但是我們很多的需求都會(huì)用到,于是只能自己想辦法實(shí)現(xiàn)了。我們可以通過適配器的getItemViewType方法來實(shí)現(xiàn)這個(gè)功能。
修改后的適配器代碼:RecyclerHeadFootViewAdapter.java
public class RecyclerHeadFootViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private List<String> datas;
private LayoutInflater inflater;
public static final int TYPE_HEADER=1;//header類型
public static final int TYPE_FOOTER=2;//footer類型
private View header=null;//頭View
private View footer=null;//腳View
public RecyclerHeadFootViewAdapter(Context context, List<String> datas){
inflater=LayoutInflater.from(context);
this.datas=datas;
}
//創(chuàng)建每一行的View 用RecyclerView.ViewHolder包裝
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType==TYPE_HEADER){
return new RecyclerView.ViewHolder(header){};
}else if(viewType==TYPE_FOOTER){
return new RecyclerView.ViewHolder(footer){};
}
View itemView=inflater.inflate(R.layout.recycler_item,null);
return new MyViewHolder(itemView);
}
//給每一行View填充數(shù)據(jù)
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position){
if(getItemViewType(position)==TYPE_HEADER||getItemViewType(position)==TYPE_FOOTER){
return;
}
MyViewHolder myholder= (MyViewHolder) holder;
myholder.textview.setText(datas.get(getRealPosition(position)));
}
//如果有頭部 position的位置是從1開始的 所以需要-1
public int getRealPosition(int position){
return header==null?position:position-1;
}
//數(shù)據(jù)源的數(shù)量
@Override
public int getItemCount() {
if(header == null && footer == null){//沒有head跟foot
return datas.size();
}else if(header == null && footer != null){//head為空&&foot不為空
return datas.size() + 1;
}else if (header != null && footer == null){//head不為空&&foot為空
return datas.size() + 1;
}else {
return datas.size() + 2;//head不為空&&foot不為空
}
}
@Override
public int getItemViewType(int position){
//如果頭布局不為空&&位置是第一個(gè)那就是head類型
if(header!=null&&position==0){
return TYPE_HEADER;
}else if(footer!=null&&position==getItemCount()-1){//如果footer不為空&&最后一個(gè)
return TYPE_FOOTER;
}
return super.getItemViewType(position);
}
public void setHeader(View header) {
this.header = header;
notifyItemInserted(0);//在位置0插入一條數(shù)據(jù),然后刷新
}
public void setFooter(View footer) {
this.footer = footer;
notifyItemInserted(datas.size()-1);//在尾部插入一條數(shù)據(jù),然后刷新
}
class MyViewHolder extends RecyclerView.ViewHolder{
private TextView textview;
public MyViewHolder(View itemView) {
super(itemView);
textview= (TextView) itemView.findViewById(R.id.textview);
}
}
}
getItemCount
有header跟footer的時(shí)候需要在源數(shù)據(jù)長度基礎(chǔ)上進(jìn)行增加。
getItemViewType
通過getItemViewType判斷不同的類型
onCreateViewHolder
通過不同的類型創(chuàng)建item的View
onBindViewHolder
如果是header跟footer類型是不需要綁定數(shù)據(jù)的,header跟footer的View一般在actvity中創(chuàng)建,不需要這邊做處理,所以這兩種類型我們就不往下執(zhí)行,如果有頭布局,position==0的位置被header占用了,但是我們的數(shù)據(jù)源也就是集合的下標(biāo)是從0開始的,所以這里需要-1。
setHeader
設(shè)置頭布局,在第一行插入一條數(shù)據(jù),然后刷新。注意這個(gè)方法調(diào)用后會(huì)有插入的動(dòng)畫,這個(gè)動(dòng)畫可以使用默認(rèn)的,也可以自己定義
setFooter
設(shè)置尾部布局,在尾部插入一條數(shù)據(jù),然后刷新。
添加header跟footer的方法終于封裝好了,在activity中只需要兩行代碼就能添加header,跟ListView調(diào)用addHeader方法一樣簡單,又可以happy的玩耍了。這里需要注意的是我們初始化View的時(shí)候,inflate方法需要三個(gè)參數(shù)。
- resource 資源id
- root 父View
- attachToRoot true:返回父View false:返回資源id生成的View
//添加header View header=LayoutInflater.from(this).inflate(R.layout.recycler_header,recyclerView,false); adapter.setHeader(header); //添加footer View footer=LayoutInflater.from(this).inflate(R.layout.recycler_footer,recyclerView,false); adapter.setFooter(footer);
recycler_header跟recycler_footer布局文件我就不貼出來了,就一個(gè)TextView,我們直接看效果圖:

item點(diǎn)擊事件&&增加或刪除帶動(dòng)畫效果
當(dāng)我們調(diào)用RecyclerView的setOnItemClickListener方法的時(shí)候,發(fā)現(xiàn)居然沒有,用了RecyclerView你要習(xí)慣什么東西都自己封裝。。。
首先我們從adapter開刀,內(nèi)部寫一個(gè)接口,一個(gè)實(shí)例變量,提供一個(gè)公共方法,設(shè)置監(jiān)聽。
private RecyclerViewItemClick recyclerViewItemClick;
public void setRecyclerViewItemClick(RecyclerViewItemClick recyclerViewItemClick) {
this.recyclerViewItemClick = recyclerViewItemClick;
}
public interface RecyclerViewItemClick{
/**
* item點(diǎn)擊
* @param realPosition 數(shù)據(jù)源position
* @param position view position
*/
void onItemClick(int realPosition,int position);
}
在onBindViewHolder方法中給item監(jiān)聽點(diǎn)擊事件
if(recyclerViewItemClick!=null) {
myholder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
recyclerViewItemClick.onItemClick(getRealPosition(position),position);
}
});
}
在activity的onCreate方法中進(jìn)行監(jiān)聽,順便設(shè)置item增加刪除動(dòng)畫。我用的是sdk自帶的默認(rèn)動(dòng)畫。
adapter.setRecyclerViewItemClick(recyclerViewItemClick); recyclerView.setItemAnimator(new DefaultItemAnimator());
private RecyclerHeadFootViewAdapter.RecyclerViewItemClick recyclerViewItemClick=new RecyclerHeadFootViewAdapter.RecyclerViewItemClick() {
@Override
public void onItemClick(int realPosition, int position) {
Log.i("ansen","刪除數(shù)據(jù):"+realPosition+" view位置:"+position);
Log.i("ansen","當(dāng)前位置:"+position+" 更新item數(shù)量:"+(adapter.getItemCount()-position-1));
datas.remove(realPosition);//刪除數(shù)據(jù)源
adapter.notifyItemRemoved(position);//item移除動(dòng)畫
//更新position至adapter.getItemCount()-1的數(shù)據(jù)
adapter.notifyItemRangeChanged(position,adapter.getItemCount()-position-1);
}
};
源碼下載
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!
- Android中RecyclerView實(shí)現(xiàn)橫向滑動(dòng)代碼
- Android中RecyclerView嵌套滑動(dòng)沖突解決的代碼片段
- Android使用RecyclerView實(shí)現(xiàn)水平滾動(dòng)控件
- Android RecyclerView 復(fù)用錯(cuò)亂通用解法詳解
- Android實(shí)現(xiàn)評(píng)論欄隨Recyclerview滑動(dòng)左右移動(dòng)
- Android中RecyclerView 滑動(dòng)時(shí)圖片加載的優(yōu)化
- 屏蔽RecyclerView單邊滑動(dòng)到頭陰影(fadingEdge)的方法
相關(guān)文章
談?wù)凙ndroid中的Divider是個(gè)什么東東
在Android應(yīng)用開發(fā)中會(huì)經(jīng)常碰到一個(gè)叫divider的東西,就是兩個(gè)View之間的分割線,本文主要給大家介紹android中的divider相關(guān)知識(shí),需要的朋友可以參考下2016-03-03
Android軟件啟動(dòng)動(dòng)畫及動(dòng)畫結(jié)束后跳轉(zhuǎn)的實(shí)現(xiàn)方法
這篇文章主要介紹了Android軟件啟動(dòng)動(dòng)畫及動(dòng)畫結(jié)束后跳轉(zhuǎn)的實(shí)現(xiàn)方法,實(shí)例分析了Android圖片播放及定時(shí)器的相關(guān)使用技巧,非常具有使用價(jià)值,需要的朋友可以參考下2015-10-10
Android中SurfaceView和view畫出觸摸軌跡
這篇文章主要介紹了Android中SurfaceView和view畫出觸摸軌跡的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-03-03
Android實(shí)現(xiàn)環(huán)形進(jìn)度條的實(shí)例
本文通過實(shí)例代碼給大家介紹了android實(shí)現(xiàn)環(huán)形進(jìn)度條的實(shí)例代碼,代碼簡單易懂,非常不錯(cuò),需要的朋友參考下2017-01-01
Android實(shí)現(xiàn)多級(jí)列表中的新建功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)多級(jí)列表中的新建功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06
Android超實(shí)用的Toast提示框優(yōu)化分享
Toast是Android中用來顯示顯示信息的一種機(jī)制,和Dialog不一樣的是,Toast是沒有焦點(diǎn)的,而且Toast顯示的時(shí)間有限,過一定的時(shí)間就會(huì)自動(dòng)消失。那么這篇文章跟大家分享下Android中Toast的優(yōu)化,對(duì)大家日常開發(fā)還是很實(shí)用,下面來一起看看吧。2016-09-09
Android Studio default not found錯(cuò)誤解決辦法
這篇文章主要介紹了Android Studio gradle 編譯提示‘default not found’ 解決辦法的相關(guān)資料,需要的朋友可以參考下2017-01-01
Android編程實(shí)現(xiàn)列表側(cè)滑刪除的方法詳解
這篇文章主要介紹了Android編程實(shí)現(xiàn)列表側(cè)滑刪除的方法,結(jié)合實(shí)例形式詳細(xì)分析了Android列表側(cè)滑刪除功能的原理與具體實(shí)現(xiàn)技巧,注釋中包含詳盡的說明,需要的朋友可以參考下2018-01-01

