• RecyclerView的使用


    1.RecyclerView:不仅可以纵向滑动,也可以横向滑动,一个加强的LIstView。

     需要在dependencies中加入

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


    2.在布局中加入控件

    <android.support.v7.widget.RecyclerView
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:id="@+id/recyclerView"/>

    3.同样需要一个子布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:layout_height="50dp">
    <ImageView
        android:layout_height="50dp"
        android:layout_width="80dp"
        android:id="@+id/imageView"
        android:src="@mipmap/ic_launcher"/>
        <TextView
            android:id="@+id/textView"
            android:layout_height="50dp"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:text="111"
            android:textColor="#000000"
            android:textSize="20dp"
            android:gravity="center_horizontal|center_vertical" />
    </LinearLayout>

    4.定义的适配器

    public class RecyclerAdapter  extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder>{
    
        List<MuInfo> data;
    
        Context context;
    
        public RecyclerAdapter(List<MuInfo> data, Context context) {
            this.data = data;
            this.context = context;
        }
    
        @Override
        public RecyclerAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    
            View view=LayoutInflater.from(context).inflate(R.layout.itme_layout, parent, false);
            final MyViewHolder holder = new MyViewHolder(view);
            holder.imageView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    int postion=holder.getAdapterPosition();
                    Toast.makeText(context,postion+"--"+data.get(postion).getName(),Toast.LENGTH_SHORT).show();
                }
            });
    
            holder.MuinfoitemView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    int postion=holder.getAdapterPosition();
                    Toast.makeText(context,postion+"--"+data.get(postion).getName()+"****",Toast.LENGTH_SHORT).show();
                }
            });
            return holder;
        }
    
        @Override
        public void onBindViewHolder(RecyclerAdapter.MyViewHolder holder, final int position) {
            MuInfo muInfo=data.get(position);
            holder.textView.setText(muInfo.getName());
            holder.imageView.setImageDrawable(context.getResources().getDrawable(R.mipmap.a));
    
    
    
        }
    
        @Override
        public int getItemCount() {
            return data.size();
        }
    
        public class MyViewHolder extends RecyclerView.ViewHolder {
            View  MuinfoitemView;
            ImageView imageView;
            TextView textView;
            public MyViewHolder(View itemView) {
                super(itemView);
                MuinfoitemView=itemView;
                imageView= (ImageView) itemView.findViewById(R.id.imageView);
                textView= (TextView) itemView.findViewById(R.id.textView);
            }
        }
    }

    5.在MainActivity中实现:下面加粗的控制RecyclerView为横向滑动,如果没有这一行,则默认为纵向滑动,和普通的ListView一样。

    
    
    public class MainActivity extends AppCompatActivity {

    List<MuInfo>data=new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    MuInfo muInfo=new MuInfo("fgehj","fghjkl");
    MuInfo muInfo1=new MuInfo("fghdfj","fghjwertkl");
    for(int i=0;i<15;i++){
    data.add(muInfo);
    data.add(muInfo1);

    }

    RecyclerView recyclerView= (RecyclerView) findViewById(R.id.recyclerView);
    LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this);
    linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
    recyclerView.setLayoutManager(linearLayoutManager);
    RecyclerAdapter adapter=new RecyclerAdapter(data,getApplicationContext());
    recyclerView.setAdapter(adapter);


    }
    }
     

    6.实体类也加上吧:

    public class MuInfo {
    
        private String name;
        private String address;
    
        public MuInfo(String name, String address) {
            this.name = name;
            this.address = address;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    }
    View Code

     二、

     1.改变子布局:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:orientation="vertical"
        android:layout_height="wrap_content">
    <ImageView
        android:layout_height="50dp"
        android:layout_width="80dp"
        android:id="@+id/imageView"
        android:src="@mipmap/ic_launcher"/>
        <TextView
            android:id="@+id/textView"
            android:layout_height="wrap_content"
            android:layout_width="80dp"
            android:text="111"
            android:textColor="#000000"
            android:textSize="20dp"
            android:gravity="center_horizontal|center_vertical" />
    </LinearLayout>

    2.

      for(int i=0;i<80;i++){
                Random random=new Random();
                int x=random.nextInt(5)+1;
                String s="好美的花";
                for(int j=0;j<x;j++){
                    s=s+"好美的花";
                }
                data.add(new MuInfo(s,s));
    
    
    
            }
    
            RecyclerView recyclerView= (RecyclerView) findViewById(R.id.recyclerView);
        // 3:控制显示为3列
    StaggeredGridLayoutManager layoutManager=new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL); recyclerView.setLayoutManager(layoutManager); RecyclerAdapter adapter=new RecyclerAdapter(data,getApplicationContext()); recyclerView.setAdapter(adapter);

    大致如:但是滑动时,并不会出现3列滑动不一致动态效果。

    三:如果实现三列,能够单独滑动?

    四:RecyclerView的分割线

    效果图:

    public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
        private int dividerHeight;
        private Paint paint;
    
    
        public SpacesItemDecoration(Context context) {
            dividerHeight = context.getResources().getDimensionPixelSize(R.dimen.margin);
            paint=new Paint();
            paint.setColor(context.getResources().getColor(R.color.colorAccent));
        }
    
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            super.getItemOffsets(outRect, view, parent, state);
            /**
             * 类似加了一个bottom的padding
             */
            outRect.bottom = dividerHeight;
        }
    
        @Override
        public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
            super.onDraw(c, parent, state);
            int childCount = parent.getChildCount();
            int left = parent.getPaddingLeft();
            int right = parent.getWidth() - parent.getPaddingRight();
    
            for (int i = 0; i < childCount - 1; i++) {
                View view = parent.getChildAt(i);
                float top = view.getBottom();
                float bottom = view.getBottom() + dividerHeight;
                /**
                 * 绘制的矩形也就是从,item的左上角,到右下角,类似于背景,
                 * 正好显示出一个横线,就是getItemOffsets空出来的范围
                 *
                 */
                c.drawRect(left, top, right, bottom, paint);
            }
        }
    }

    MainActivity只需要在SetAdapter后加入二行代码就可以了:

    SpacesItemDecoration decoration=new SpacesItemDecoration(getApplicationContext());
            recyclerView.addItemDecoration(decoration);

    上面的代码中SpacesItemDecoration如果不重写OnDraw方法,那么实现的效果只是相当于在item之间空出了距离。

    也就是说在ItemDecoration中的方法:

    getItemOffsets(),可以实现类似padding的效果

    onDraw(),可以实现类似绘制背景的效果,item内容在上面

    onDrawOver(),可以绘制在内容的上面,覆盖在item内容

    onDrawOver的实现可以一试:想如下:

    public class LeftAndRightTagDecoration extends RecyclerView.ItemDecoration{
        private int tagWidth;
        private Paint leftPaint;
        private Paint rightPaint;
    
        public LeftAndRightTagDecoration(Context context) {
            leftPaint = new Paint();
            leftPaint.setColor(context.getResources().getColor(R.color.colorAccent));
            rightPaint = new Paint();
            rightPaint.setColor(context.getResources().getColor(R.color.colorPrimary));
            tagWidth = context.getResources().getDimensionPixelSize(R.dimen.activity_horizontal_margin);
        }
    
        @Override
        public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
            super.onDrawOver(c, parent, state);
            int childCount = parent.getChildCount();
            for (int i = 0; i < childCount; i++) {
                View child = parent.getChildAt(i);
                int pos = parent.getChildAdapterPosition(child);
                boolean isLeft = pos % 2 == 0;
                if (isLeft) {
                    float left = child.getLeft();
                    float right = left + tagWidth;
                    float top = child.getTop();
                    float bottom = child.getBottom();
                    c.drawRect(left, top, right, bottom, leftPaint);
                } else {
                    float right = child.getRight();
                    float left = right - tagWidth;
                    float top = child.getTop();
                    float bottom = child.getBottom();
                    c.drawRect(left, top, right, bottom, rightPaint);
    
                }
            }
        }
    }

    在这里 recyclerView.addItemDecoration(decoration);是可以叠加的,可以同时实现加分割线,也可以同时在左右侧加覆盖标签。

    <------------------------------------------------------------------------------------------------------------------------------------------------------------------------------->

    待续……

    根据数据源,分组实现如图的效果:

    public class SectionDecoration extends RecyclerView.ItemDecoration {
        private static final String TAG = "SectionDecoration";
    
        private DecorationCallback callback;
        private TextPaint textPaint;
        private Paint paint;
        private int topGap;
        private Paint.FontMetrics fontMetrics;
    
    
        public SectionDecoration(Context context, DecorationCallback decorationCallback) {
            Resources res = context.getResources();
            this.callback = decorationCallback;
    
            paint = new Paint();
            paint.setColor(res.getColor(R.color.colorAccent));
    
            textPaint = new TextPaint();
            textPaint.setTypeface(Typeface.DEFAULT_BOLD);
            textPaint.setAntiAlias(true);
            textPaint.setTextSize(80);
            textPaint.setColor(Color.BLACK);
            textPaint.getFontMetrics(fontMetrics);
            textPaint.setTextAlign(Paint.Align.LEFT);
            fontMetrics = new Paint.FontMetrics();
            topGap = res.getDimensionPixelSize(R.dimen.margin1);//32dp
    
    
        }
    
    
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            super.getItemOffsets(outRect, view, parent, state);
            int pos = parent.getChildAdapterPosition(view);
            Log.i(TAG, "getItemOffsets:" + pos);
            long groupId = callback.getGroupId(pos);
            if (groupId < 0) return;
            if (pos == 0 || isFirstInGroup(pos)) {//同组的第一个才添加padding
                outRect.top = topGap;
            } else {
                outRect.top = 0;
            }
        }
    
        @Override
        public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
            super.onDraw(c, parent, state);
            int left = parent.getPaddingLeft();
            int right = parent.getWidth() - parent.getPaddingRight();
            int childCount = parent.getChildCount();
            for (int i = 0; i < childCount; i++) {
                View view = parent.getChildAt(i);
                int position = parent.getChildAdapterPosition(view);
                long groupId = callback.getGroupId(position);
                if (groupId < 0) return;
                String textLine = callback.getGroupFirstLine(position).toUpperCase();
                if (position == 0 || isFirstInGroup(position)) {
                    float top = view.getTop() - topGap;
                    float bottom = view.getTop();
                    c.drawRect(left, top, right, bottom, paint);//绘制红色矩形
                    c.drawText(textLine, left, bottom, textPaint);//绘制文本
                }
            }
        }
    
    
        private boolean isFirstInGroup(int pos) {
            if (pos == 0) {
                return true;
            } else {
                long prevGroupId = callback.getGroupId(pos - 1);
                long groupId = callback.getGroupId(pos);
                return prevGroupId != groupId;
            }
        }
    
        public interface DecorationCallback {
    
            long getGroupId(int position);
    
            String getGroupFirstLine(int position);
        }
    }
    public interface DecorationCallback {
        long getGroupId(int position);
    
        String getGroupFirstLine(int position);
    }

    MainActivity加入代码:

    recyclerView.addItemDecoration(new SectionDecoration(this, new SectionDecoration.DecorationCallback() {
                @Override
                public long getGroupId(int position) {
                    return Character.toUpperCase(data.get(position).getName().charAt(0));
                }
    
                @Override
                public String getGroupFirstLine(int position) {
                    return data.get(position).getName().substring(0, 1).toUpperCase();
                }
            }));

    但是上图中,A,B,C,分组标题也会随着item而不停的移动:

    如何实现吸顶效果:看代码:

    public class PinnedSectionDecoration extends RecyclerView.ItemDecoration {
        private static final String TAG = "PinnedSectionDecoration";
    
        private DecorationCallback callback;
        private TextPaint textPaint;
        private Paint paint;
        private int topGap;
        private Paint.FontMetrics fontMetrics;
    
    
        public PinnedSectionDecoration(Context context, DecorationCallback decorationCallback) {
            Resources res = context.getResources();
            this.callback = decorationCallback;
    
            paint = new Paint();
            paint.setColor(res.getColor(R.color.colorAccent));
    
            textPaint = new TextPaint();
            textPaint.setTypeface(Typeface.DEFAULT_BOLD);
            textPaint.setAntiAlias(true);
            textPaint.setTextSize(80);
            textPaint.setColor(Color.BLACK);
            textPaint.getFontMetrics(fontMetrics);
            textPaint.setTextAlign(Paint.Align.LEFT);
            fontMetrics = new Paint.FontMetrics();
            topGap = res.getDimensionPixelSize(R.dimen.margin1);
    
    
        }
    
        public interface DecorationCallback {
    
            long getGroupId(int position);
    
            String getGroupFirstLine(int position);
        }
        private boolean isFirstInGroup(int pos) {
            if (pos == 0) {
                return true;
            } else {
                long prevGroupId = callback.getGroupId(pos - 1);
                long groupId = callback.getGroupId(pos);
                return prevGroupId != groupId;
            }
        }
    
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            super.getItemOffsets(outRect, view, parent, state);
            int pos = parent.getChildAdapterPosition(view);
            long groupId = callback.getGroupId(pos);
            if (groupId < 0) return;
            if (pos == 0 || isFirstInGroup(pos)) {
                outRect.top = topGap;
            } else {
                outRect.top = 0;
            }
        }
    
    
        @Override
        public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
            super.onDrawOver(c, parent, state);
            int itemCount = state.getItemCount();
            int childCount = parent.getChildCount();
            int left = parent.getPaddingLeft();
            int right = parent.getWidth() - parent.getPaddingRight();
            float lineHeight = textPaint.getTextSize() + fontMetrics.descent;
    
            long preGroupId, groupId = -1;
            for (int i = 0; i < childCount; i++) {
                View view = parent.getChildAt(i);
                int position = parent.getChildAdapterPosition(view);
    
                preGroupId = groupId;
                groupId = callback.getGroupId(position);
                if (groupId < 0 || groupId == preGroupId) continue;
    
                String textLine = callback.getGroupFirstLine(position).toUpperCase();
                if (TextUtils.isEmpty(textLine)) continue;
    
                int viewBottom = view.getBottom();
                float textY = Math.max(topGap, view.getTop());
                if (position + 1 < itemCount) { //下一个和当前不一样移动当前
                    long nextGroupId = callback.getGroupId(position + 1);
                    if (nextGroupId != groupId && viewBottom < textY ) {//组内最后一个view进入了header
                        textY = viewBottom;
                    }
                }
                c.drawRect(left, textY - topGap, right, textY, paint);
                c.drawText(textLine, left, textY, textPaint);
            }
    
        }
    
    }

    MainActivity代码:

            recyclerView.addItemDecoration(new PinnedSectionDecoration(this, new PinnedSectionDecoration.DecorationCallback() {
                @Override
                public long getGroupId(int position) {
                    return Character.toUpperCase(data.get(position).getName().charAt(0));
                }
    
                @Override
                public String getGroupFirstLine(int position) {
                    return data.get(position).getName().substring(0, 1).toUpperCase();
                }
            }));
     code地址:
    http://pan.baidu.com/s/1eRM2XsI
    今天多一点积累,明天少一分烦恼
  • 相关阅读:
    .Net Core2.1 秒杀项目一步步实现CI/CD(Centos7.2)系列一:Docker入门
    在ASP.Net Core 中使用枚举类而不是枚举
    ASP.Net Core 中使用Zookeeper搭建分布式环境中的配置中心系列一:使用Zookeeper.Net组件演示基本的操作
    Redis系列文章总结:ASP.Net Core 中如何借助CSRedis实现一个安全高效的分布式锁
    从源码中学习设计模式系列——单例模式序/反序列化以及反射攻击的问题(二)
    ASP.NET Core依赖注入——依赖注入最佳实践
    2019年第一天——使用Visual Studio 2019 Preview创建第一个ASP.Net Core3.0的App
    ASP.Net Core2.1中的HttpClientFactory系列二:集成Polly处理瞬态故障
    ASP.Net Core2.1中的HttpClientFactory系列一:HttpClient的缺陷
    Docker for .Net Developers(part1:Docker基本概念介绍)
  • 原文地址:https://www.cnblogs.com/galibujianbusana/p/6394751.html
Copyright © 2020-2023  润新知