高级UIrecycleview

RecyClerView列表关于

2019-07-23  本文已影响3人  玖玖君

简单使用

LinearLayoutManager 线性管理器(支持横向、纵向)
GridLayoutManager 网格布局管理器
StaggeredGridLayoutManager 瀑布流式布局管理器

recyclerView.setLayoutManager(new LinearLayoutManager(this));
// 如果可以确定每个 item 的高度是固定的,设置这个选项可以提高性能
recyclerView.setHasFixedSize(true);
// item 显示的动画
recyclerView.setItemAnimator(new DefaultItemAnimator());  
recyclerView.setAdapter(new MyAdapter());

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    public List<String> datas;
    public MyAdapter(List<String> datas) {
        this.datas = datas;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int position) {
        viewHolder.mTextView.setText(datas.get(position));
    }

    @Override
    public int getItemCount() {
        return datas.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public TextView mTextView;
        public ViewHolder(View view){
            super(view);
            mTextView = (TextView) view.findViewById(R.id.text);
        }
    }
}

多种布局

public class MyAdapter extends RecyclerView.Adapter {
    public List<String> datas;
    public MyAdapter(List<String> datas) {
        this.datas = datas;
    }

    public enum ITEM_TYPE {
        ITEM1, ITEM2
    }

    @Override
    public int getItemViewType(int position) {
        // Enum 类提供了一个 ordinal() 方法,返回枚举类型的序数
        // ITEM_TYPE.ITEM1.ordinal() 代表0, ITEM_TYPE.ITEM2.ordinal() 代表1
        return position % 2 == 0 ? ITEM_TYPE.ITEM1.ordinal() : ITEM_TYPE.ITEM2.ordinal();
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // 根据不同 viewType 加载不同的布局
        if (viewType == ITEM_TYPE.ITEM1.ordinal()) {
            View view1 = LayoutInflater.from(parent.getContext()).inflate(R.layout.item1, parent, false);
            return new ViewHolder1(view1);
        } else if (viewType == ITEM_TYPE.ITEM2.ordinal()) {
            View view2 = LayoutInflater.from(parent.getContext()).inflate(R.layout.item2, parent, false);
            return new ViewHolder2(view2);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
        if (holder instanceof ViewHolder1) {
            ((ViewHolder1) holder).mTextView.setText(datas.get(position));
        } else if (holder instanceof ViewHolder2) {
            ((ViewHolder2) holder).mTextView.setText(datas.get(position)+"abc");
        }
    }

    @Override
    public int getItemCount() {
        return datas.size();
    }

    public static class ViewHolder1 extends RecyclerView.ViewHolder {
        public TextView mTextView;
        public ViewHolder(View view){
            super(view);
            mTextView = (TextView) view.findViewById(R.id.text);
        }
    }

    public static class ViewHolder2 extends RecyclerView.ViewHolder {
        public TextView mTextView;
        public ViewHolder(View view){
            super(view);
            mTextView = (TextView) view.findViewById(R.id.big_text);
        }
    }
}

分隔线 ItemDecoration

自定义分隔线

定义分隔线 divider.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#7b7a7a"/>
    <size android:height="1dp"/>
</shape>

自定义类继承 RecyclerView.ItemDecoration,重写回调方法

// 线性布局用
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;

public class MyDecoration extends RecyclerView.ItemDecoration{

    private Context mContext;
    private Drawable mDivider;
    private int mOrientation;
    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;

    public MyDecoration(Context context, int orientation) {
        this.mContext = context;
        mDivider = context.getResources().getDrawable(R.drawable.divider);
        setOrientation(orientation);
    }

    // 设置屏幕的方向
    public void setOrientation(int orientation){
        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST){
            throw new IllegalArgumentException("invalid orientation");        
        }        
        mOrientation = orientation;
    }

   @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == HORIZONTAL_LIST){
            drawVerticalLine(c, parent, state);
        }else {
            drawHorizontalLine(c, parent, state);
        }
    }

    // 画竖线, 这里的 parent 其实是显示在屏幕显示的这部分
    public void drawVerticalLine(Canvas c, RecyclerView parent, RecyclerView.State state){
        int left = parent.getPaddingLeft();
        int right = parent.getWidth() - parent.getPaddingRight();
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++){
            final View child = parent.getChildAt(i);

            // 获得 child 的布局信息
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)child.getLayoutParams();
            final int top = child.getBottom() + params.bottomMargin;
            final int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    // 画横线
    public void drawHorizontalLine(Canvas c, RecyclerView parent, RecyclerView.State state){
        int top = parent.getPaddingTop();
        int bottom = parent.getHeight() - parent.getPaddingBottom();
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++){
            final View child = parent.getChildAt(i);

           // 获得 child 的布局信息
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)child.getLayoutParams();
            final int left = child.getRight() + params.rightMargin;
            final int right = left + mDivider.getIntrinsicWidth();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }
 
    // 由于 Divider 也有长宽高,每一个 Item 需要向下或者向右偏移
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        if(mOrientation == HORIZONTAL_LIST){
            // 画竖线,就是往右偏移一个分割线的宽度
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        } else {
            // 画横线,就是往下偏移一个分割线的高度
            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
        }
    }
}
// 网格或瀑布流布局用

public class DividerGridItemDecoration extends RecyclerView.ItemDecoration {
    private static final int[] ATTRS = new int[] { android.R.attr.listDivider };
    private Drawable mDivider;

    public DividerGridItemDecoration(Context context) {
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, State state) {
        drawHorizontal(c, parent);
        drawVertical(c, parent);
    }

    private int getSpanCount(RecyclerView parent) {
        // 列数
        int spanCount = -1;
        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 c, 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
                    + mDivider.getIntrinsicWidth();
            final int top = child.getBottom() + params.bottomMargin;
            final int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    public void drawVertical(Canvas c, 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 + mDivider.getIntrinsicWidth();

            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    private boolean isLastColum(RecyclerView parent, int pos, int spanCount, int childCount) {
        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 isLastRaw(RecyclerView parent, int pos, int spanCount, int childCount) {
        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();
            // StaggeredGridLayoutManager 且纵向滚动
            if (orientation == StaggeredGridLayoutManager.VERTICAL) {
                childCount = childCount - childCount % spanCount;
                // 如果是最后一行,则不需要绘制底部
                if (pos >= childCount)
                    return true;
            } else { // StaggeredGridLayoutManager 且横向滚动
                // 如果是最后一行,则不需要绘制底部
                if ((pos + 1) % spanCount == 0) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
        int spanCount = getSpanCount(parent);
        int childCount = parent.getAdapter().getItemCount();
        if (isLastRaw(parent, itemPosition, spanCount, childCount)) { // 如果是最后一行,则不需要绘制底部  
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        } else if (isLastColum(parent, itemPosition, spanCount, childCount)) { // 如果是最后一列,则不需要绘制右边
            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
        } else {
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), mDivider.getIntrinsicHeight());
        }
    }
}

使用自定义分隔线:

mRecyclerView.addItemDecoration(new MyDecoration(this, MyDecoration.VERTICAL_LIST));

使用自带的分隔线

mRecyclerView.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.HORIZONTAL));

可以更改自带分隔线的样式:

<style name="AppTheme" parent="AppBaseTheme">
    <item name="android:listDivider">@drawable/divider_bg</item>  
</style>

可以自己画个分隔线 shape。
item 选择器
给 item 设置一个 selector,设置 android:state_focused 不同时不同的背景,关键是要在 item 根布局设置

android:focusable="true"
android:clickable="true"
android:focusableInTouchMode="true"

item 有 EditText
TextWatcher 问题
EditText 添加 TextWatcher 后,每次执行刷新、添加数据之类的操作,即只要执行 onBindViewHolder 就会进入监听,导致数据错乱。
解决方法时一开始先移除监听:

holder.tvOrderGoodsQuantity.removeTextChangedListener((QunaitityWatcher) holder.tvOrderGoodsQuantity.getTag());

然后做完数据操作后,再添加:

QunaitityWatcher watcher = new QunaitityWatcher(holder.tvOrderGoodsQuantity, holder.tvOrderGoodsQuantity, mData, holder.tvOrderGoodsAmount);
holder.tvOrderGoodsQuantity.addTextChangedListener(watcher);

自定义 TextWatcher,把一些 View 作为参数传入,以免数据错乱,不然可能会传到其它 item 的 View 上。

private class QunaitityWatcher implements TextWatcher {
    private EditText editText;
    private GoodModel model;
    private TextView tv;
    private EditText et;
    public QunaitityWatcher(EditText et, EditText editText, GoodModel model, TextView tv) {
        this.et = et;
        this.editText = editText;
        this.model = model;
        this.tv = tv;

        et.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus)
                    et.setText(Utils.subZeroAndDot(model.getScatterGoodQuantity()));
            }
        });
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {
        String text = s.toString();
        if (!TextUtils.isEmpty(text) && Utils.isDouble(text) && !text.startsWith(".")) {
            double d = Double.parseDouble(text);
            if (d <= 0) {
                editText.setText("1"); // 默认的 1 件
                d = 1;
            } else {
                int dotindex = text.indexOf(".");
                if (dotindex > 0 && text.length() > dotindex + 3) {
                    s.delete(dotindex + 3, text.length());
                } else {
                    d = Double.parseDouble(s.toString());
                }
            }
            tv.setText("¥" + Utils.subZeroAndDot(d * model.getPrice()));
            model.setScatterGoodQuantity(d);
            EventBus.getDefault().post(new ChangeGoodQuantityEvent());
            refreshQuantityAndPrice();
        }
    }
}

Edittext 获取不到焦点
因为 EditText 默认 FocusableInTouchMode 为 false,需设置

et.setFocusableInTouchMode(true);
et.requestFocus();

是否到达最底部
方法一:

public static boolean isVisBottom(RecyclerView recyclerView){
    LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();  
    // 屏幕中最后一个可见子项的 position
    int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition();  
    // 当前屏幕所看到的子项个数
    int visibleItemCount = layoutManager.getChildCount();  
    // 当前 RecyclerView 的所有子项个数
    int totalItemCount = layoutManager.getItemCount();  
    // RecyclerView 的滑动状态
    int state = recyclerView.getScrollState();  
    if(visibleItemCount > 0 && lastVisibleItemPosition == totalItemCount - 1 && state == recyclerView.SCROLL_STATE_IDLE){
        return true;
    } else {   
        return false;  
    }
}

方法二:

public static boolean isSlideToBottom(RecyclerView recyclerView) {    
   if (recyclerView == null) return false;
   if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset()
        >= recyclerView.computeVerticalScrollRange())   
     return true;  
   return false;
}

computeVerticalScrollExtent() 是当前屏幕显示的区域高度,
computeVerticalScrollOffset() 是当前屏幕之前滑过的距离,
而 computeVerticalScrollRange() 是整个 View 控件的高度。

方法三:

RecyclerView.canScrollVertically(1) 的返回值表示是否能向上滚动,false 表示已经滚动到底部
RecyclerView.canScrollVertically(-1) 的返回值表示是否能向下滚动,false 表示已经滚动到顶部

跨列
复杂的不规则列(有的行显示的列数多,有的行显示的列数少,并且每列显示的内容页不一样),使用 GridLayoutManager.SpanSizeLookup 的相关功能实现,新建 GridLayoutManager 的时候列数填写所有可能列数的最小公倍数。再结合 adapter 中的:

GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 2);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
    @Override
    public int getSpanSize(int position) {
        // 设置对应 position 位置的 item 的跨列数,比如第一行占两列,其他行每个 Item 占一列
        return position == 0 ? 2 : 1;
    }
});
recyclerView.setLayoutManager(layoutManager);

智能

智能是什么玩意?有什么用?智能主要体现 SmartRefreshLayout 对未知布局的自动识别上,这样可以让我们更高效的实现我们所需的功能,也可以实现一些非寻常的功能。下面通过自定义Header嵌套Layout作为内容 来解释 SmartRefreshLayout 的智能之处。

自定义Header

我们来看这一下这个伪代码例子:

    <SmartRefreshLayout>
        <ClassicsHeader/>
        <TextView/>
        <ClassicsFooter/>
    </SmartRefreshLayout>

在Android Studio 中的预览效果图

image

对比代码和我们预想的一样,那我们来对代码做一些改动,ClassicsHeader换成一个简单的TextView,看看会发生什么?

    <SmartRefreshLayout>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:gravity="center"
            android:background="#444"
            android:textColor="#fff"
            android:text="看看我会不会变成Header"/>
        <TextView/>
        <ClassicsFooter/>
    </SmartRefreshLayout>

在Android Studio 中的预览效果图 和 运行效果图

我们注意看右边的图,仔细观察手指触摸的位置和下拉效果。可以看到在列表已经滚动到中部时,轻微下拉列表是不会触发刷新的,但是如果是触摸固定的布局,则可以触发下拉。从这里可以看出 SmartRefreshLayout 对滚动边界的判断是动态的,智能的!当然如果 SmartRefreshLayout 的智能还是不能满足你,可以通过 setListener 自己实现滚动边界的判断,更为准确!
这时发现我们我们替换的 TextView 自动就变成了Header,只是它还不会动。要动起来?

接着我们来改代码:

compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.3'//一个开源gif控件

    <SmartRefreshLayout>
        <pl.droidsonroids.gif.GifImageView
            android:layout_width="match_parent"
            android:layout_height="150dp"
            android:scaleType="centerCrop"
            android:src="@mipmap/gif_header_repast"/>
        <ListView/>
        <ClassicsFooter/>
    </SmartRefreshLayout>

在 Android Studio 中的预览效果图 和 运行效果图

image

哈哈!一行Java代码都不用写,就完成了一个自定义的Header

嵌套Layout作为内容

如果boos要求在列表的前面固定一个广告条怎么办?这好办呀,一般我们会开开心心的下下这样的代码:

<LinearLayout
    android:orientation="vertical">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:gravity="center"
        android:text="我就是boos要求加上的广告条啦"/>
    <SmartRefreshLayout>
        <ListView/>
    </SmartRefreshLayout>
</LinearLayout>

但是在运行下拉刷新的时候,我们发现 Header是在广告条之下的,看着会别扭~,其实我们可以试试另一种方式,把广告条写到 RefreshLayout内部,看看会发生什么?

<SmartRefreshLayout>
    <LinearLayout
        android:orientation="vertical">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:gravity="center"
            android:text="我就是boos要求加上的广告条啦"/>
        <ListView/>
    </LinearLayout>
</SmartRefreshLayout>

由于伪代码过于简单,而且运行效果过于丑陋,这里还是贴出在实际项目中的实际情况吧~

image image

我们注意看右边的图,仔细观察手指触摸的位置和下拉效果。可以看到在列表已经滚动到中部时,轻微下拉列表是不会触发刷新的,但是如果是触摸固定的布局,则可以触发下拉。从这里可以看出 SmartRefreshLayout 对滚动边界的判断是动态的,智能的!当然如果 SmartRefreshLayout 的智能还是不能满足你,可以通过 setListener 自己实现滚动边界的判断,更为准确!

功能

简单的介绍了两大特点框架和智能,接下来也说说SmartRefreshLayout还具有的其他常用功能吧~


使用

简单用例

1.在 buld.gradle 中添加依赖

compile 'com.android.support:appcompat-v7:25.3.1'//版本随意
compile 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.4'
compile 'com.scwang.smartrefresh:SmartRefreshHeader:1.0.4'//没有使用特殊Header,可以不加这行

2.在XML布局文件中添加 SmartRefreshLayout

<?xml version="1.0" encoding="utf-8"?>
<com.scwang.smartrefresh.layout.SmartRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/refreshLayout"
    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"
        android:overScrollMode="never"
        android:background="#fff" />
</com.scwang.smartrefresh.layout.SmartRefreshLayout>

3.在 Activity 或者 Fragment 中添加代码

RefreshLayout refreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout);
refreshLayout.setOnRefreshListener(new OnRefreshListener() {
    @Override
    public void onRefresh(RefreshLayout refreshlayout) {
        refreshlayout.finishRefresh(2000);
    }
});
refreshLayout.setOnLoadmoreListener(new OnLoadmoreListener() {
    @Override
    public void onLoadmore(RefreshLayout refreshlayout) {
        refreshlayout.finishLoadmore(2000);
    }
});

使用指定的 Header 和 Footer

1.方法一 全局设置

public class App extends Application {
    static {//static 代码段可以防止内存泄露
        //设置全局的Header构建器
        SmartRefreshLayout.setDefaultRefreshHeaderCreater(new DefaultRefreshHeaderCreater() {
                @Override
                public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) {
                    layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white);//全局设置主题颜色
                    return new ClassicsHeader(context).setSpinnerStyle(SpinnerStyle.Translate);//指定为经典Header,默认是 贝塞尔雷达Header
                }
            });
        //设置全局的Footer构建器
        SmartRefreshLayout.setDefaultRefreshFooterCreater(new DefaultRefreshFooterCreater() {
                @Override
                public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) {
                    //指定为经典Footer,默认是 BallPulseFooter
                    return new ClassicsFooter(context).setSpinnerStyle(SpinnerStyle.Translate);
                }
            });
    }
}

注意:方法一 设置的Header和Footer的优先级是最低的,如果同时还使用了方法二、三,将会被其他方法取代

2.方法二 XML布局文件指定

    <com.scwang.smartrefresh.layout.SmartRefreshLayout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/smartLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#444444"
        app:srlPrimaryColor="#444444"
        app:srlAccentColor="@android:color/white"
        app:srlEnablePreviewInEditMode="true">
        <!--srlAccentColor srlPrimaryColor 将会改变 Header 和 Footer 的主题颜色-->
        <!--srlEnablePreviewInEditMode 可以开启和关闭预览功能-->
        <com.scwang.smartrefresh.layout.header.ClassicsHeader
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="@dimen/padding_common"
            android:background="@android:color/white"
            android:text="@string/description_define_in_xml"/>
        <com.scwang.smartrefresh.layout.footer.ClassicsFooter
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </com.scwang.smartrefresh.layout.SmartRefreshLayout>

注意:方法二 XML设置的Header和Footer的优先级是中等的,会被方法三覆盖。而且使用本方法的时候,Android Studio 会有预览效果,如下图:

image

不过不用担心,只是预览效果,运行的时候只有下拉才会出现~

上一篇下一篇

猜你喜欢

热点阅读