Android RecyclerView 向上偏移解决、添加自定义分割线,瀑布流,ScrollView嵌套RecyclerView滑动卡顿

 向上偏移解决

android:focusableInTouchMode="true"
android:focusable="true"
android:fillViewport="true"

 

卡顿解决方法

recyclerViewwg.setHasFixedSize(true);
recyclerViewwg.setNestedScrollingEnabled(false);

删除条目:

lists.remove(i); notifyItemRemoved(i); notifyDataSetChanged();

 mRecyclerview.invalidate();====mRecyAdapter.notifyDataSetChanged();

 

概述

RecyclerView出现已经有一段时间了,相信大家肯定不陌生了,大家可以通过导入support-v7对其进行使用。
据官方的介绍,该控件用于在有限的窗口中展示大量数据集,其实这样功能的控件我们并不陌生,例如:ListView、GridView。

那么有了ListView、GridView为什么还需要RecyclerView这样的控件呢?整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现令人瞠目的效果。

  • 你想要控制其显示的方式,请通过布局管理器LayoutManager
  • 你想要控制Item间的间隔(可绘制),请通过ItemDecoration
  • 你想要控制Item增删的动画,请通过ItemAnimator
  • 你想要控制点击、长按事件,请自己写(擦,这点尼玛。)

一.RecyclerView介绍

RecyclerView 是Android 5.0版本中新出现的东西,用来替代ListView和GridView的。

二.RecyclerView架构

RecyclerView使用布局管理器LayoutManager和适配器Adapter的适配器模式去实现架构,不关心数据的来源。耦合性非常的底,用户可以根据自己的用户界面去实现相应的效果

三.RecyclerView的优点

  • 1.RecyclerView内部已经强制使用VIewHolder,优化了对Item中View的复用。

  • 2.提供了一个较为灵活的布局管理类,LayoutManager,用来控制RecyclerView是线性展示还是垂直展示,以及可以设置成瀑布流。并且提供了ItemDecoration这个类,来灵活的让用户来设置分割线。

  • 3.用ItemAnimator可以对item进行布局的删减动画效果。

 

设置布局管理器:

1、竖向listview

rv.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));

2、横向listview

rv.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));

3、竖向gridView

rv.setLayoutManager(new GridLayoutManager(this, 5));

4、横向gridview

rv.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
rv.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.HORIZONTAL));

5、瀑布流

rv.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
rv.setLayoutManager(new StaggeredGridLayoutManager(5, StaggeredGridLayoutManager.VERTICAL));

瀑布流实现效果

 

 实现方法

item类型设置

for (int a=0;a<8;a++){TuijianMainEntity tuijianEntity =new TuijianMainEntity();tuijianEntity.setUname("网吧"+a);if (a>0){if (iflong){tuijianEntity.setIflong(iflong);intlonglg++;if (intlonglg==2){iflong=!iflong;intlonglg=0;}}else {tuijianEntity.setIflong(iflong);intlonglg++;if (intlonglg==2){iflong=!iflong;intlonglg=0;}}}barEntityList.add(tuijianEntity);
}

设置左右间隙

if (position%2==0){holder.itemView.setPadding(12,28,12,0);}else {holder.itemView.setPadding(12,28,12,0);
}

设置图片高度

        if (entityList.get(position).isIflong()){int h = (int)Math.floor(heightlg*4/7)-130;int igh = h-210;
//            setViewLayoutParams(holder.myli,h);setigLayoutParams(holder.myig,igh);}else {int h = (int)Math.floor(heightlg*3/7)-80;int igh = h-160;
//            setViewLayoutParams(holder.myli,h);setigLayoutParams(holder.myig,igh);}

item_layout 自适应高度wrap_content

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:background="@color/bg_list"android:layout_height="wrap_content"><LinearLayoutandroid:id="@+id/myli"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"android:background="@drawable/kongwhitebg">

 

需在adapter随机设置高度

rvAdapter.setType(3);
private int type = 0;public RvAdapter(Context context, List<Integer> datas) {this.context = context;this.datas = datas;for (int i : datas) {int height = (int) (Math.random() * 100 + 300);heights.add(height);}
}public void setType(int type) {this.type = type;
}
@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {RecyclerView.LayoutParams layoutParams;if (type == 0) {layoutParams = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);} else if (type == 1) {layoutParams = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);} else {layoutParams = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, heights.get(position));layoutParams.setMargins(2, 2, 2, 2);}

设置Item增加、移除动画:

rv.setItemAnimator(new DefaultItemAnimator());

实现添加分割线:

1、添加默认分割线

//分割线
private RecyclerView.ItemDecoration itemDecoration;
        itemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
//默认分割线mHistoryRecycle.addItemDecoration(itemDecoration);

2、添加自定义分割线

mHistoryRecycle.addItemDecoration(new RecyclerViewDivider(this, LinearLayoutManager.HORIZONTAL,15, R.color.video_btn_danmaku_control_color, 2, 0));

自定义类RecyclerViewDivider

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;import com.baidu.api.Util;
import com.juejinchain.android.R;/*** 作者:created by meixi* 邮箱:15913707499@163.com* 日期:2019/6/14 08*/
public class RecyclerViewDivider extends RecyclerView.ItemDecoration {private Paint mPaint;private Drawable mDivider;private int mDividerSize = 2;//分割线高度,默认为1pxprivate int mOffsetStart = 0;private int mOffsetEnd = 0;private int mOrientation;//列表的方向:LinearLayoutManager.VERTICAL或LinearLayoutManager.HORIZONTALprivate static final int[] ATTRS = new int[]{android.R.attr.listDivider};/*** 默认分割线:高度为2px,颜色为灰色** @param context* @param orientation 列表方向*/private RecyclerViewDivider(Context context, int orientation) {if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) {throw new IllegalArgumentException("请输入正确的参数!");}mOrientation = orientation;final TypedArray a = context.obtainStyledAttributes(ATTRS);mDivider = a.getDrawable(0);a.recycle();}/*** 自定义分割线** @param context* @param orientation 列表方向* @param drawableId  分割线图片*/public RecyclerViewDivider(Context context, int orientation, int drawableId) {this(context, orientation);mDivider = ContextCompat.getDrawable(context, drawableId);mDividerSize = mDivider.getIntrinsicHeight();}/*** 自定义分割线** @param context* @param orientation  列表方向* @param dividerSize  分割线高度* @param dividerColor 分割线颜色*/public RecyclerViewDivider(Context context, int orientation, int dividerSize, @ColorRes int dividerColor) {this(context, orientation);mDividerSize = dividerSize;mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setColor(context.getResources().getColor(dividerColor));mPaint.setStyle(Paint.Style.FILL);}/*** 自定义分割线** @param context       context* @param orientation   列表方向* @param dividerHeight 分割线高度* @param dividerColor  分割线颜色* @param offsetStart   起始偏移量* @param offsetEnd     结束偏移量*/public RecyclerViewDivider(Context context, int orientation, int dividerHeight, @ColorRes int dividerColor, int offsetStart, int offsetEnd) {this(context, orientation);mDividerSize = dividerHeight;mOffsetStart = dip2px(context, offsetStart);mOffsetEnd = dip2px(context, offsetEnd);mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);if (dividerColor == 0) {dividerColor = R.color.red_500;}mPaint.setColor(context.getResources().getColor(dividerColor));mPaint.setStyle(Paint.Style.FILL);}public static int dip2px(Context context, float dipValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (dipValue * scale + 0.5f);}//重写此方法,防止设置的波纹背景把分隔线覆盖掉。@Overridepublic void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {RecyclerView.ViewHolder childViewHolder = parent.getChildViewHolder(view);if (childViewHolder.getItemViewType() != 0) {outRect.set(0, 0, 0, 0);return;}if (mOrientation == LinearLayoutManager.HORIZONTAL) {outRect.set(0, 0, 0, mDividerSize);} else {outRect.set(0, 0, mDividerSize, 0);}}//绘制分割线@Overridepublic void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {if (mOrientation == LinearLayoutManager.VERTICAL) {drawVertical(c, parent);} else {drawHorizontal(c, parent);}}//绘制横向 item 分割线private void drawHorizontal(Canvas canvas, RecyclerView parent) {final int left = parent.getPaddingLeft() + mOffsetStart;final int right = parent.getMeasuredWidth() - (parent.getPaddingRight() + mOffsetEnd);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 + mDividerSize;if (mDivider != null) {mDivider.setBounds(left, top, right, bottom);mDivider.draw(canvas);}if (mPaint != null) {canvas.drawRect(left, top, right, bottom, mPaint);}}}//绘制纵向 item 分割线private void drawVertical(Canvas canvas, RecyclerView parent) {final int top = parent.getPaddingTop() + mDividerSize;final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom() + mDividerSize;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 + mDividerSize;if (mDivider != null) {mDivider.setBounds(left, top, right, bottom);mDivider.draw(canvas);}if (mPaint != null) {canvas.drawRect(left, top, right, bottom, mPaint);}}}
}

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/415101.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端学习(2678):懂代码之表格BaseTable编辑操作

第一步:编辑操作 <template slot-scope"scope"><el-buttontype"text"icon"el-icon-edit"click"handleEdit(scope.$index, scope.row)">编辑</el-button></template> 第二步 进行编辑处理 // 编辑操作handle…

vue-cli3配置externals、jquery

在index.html引入 <script src"https://cdn.bootcdn.net/ajax/libs/jquery/1.10.0/jquery.js"></script>配置文件 vue.config.js 代码如下&#xff1a; module.exports {configureWebpack:{externals: {jquery : $,}}, };

QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开

版权声明&#xff1a;若无来源注明&#xff0c;Techie亮博客文章均为原创。 转载请以链接形式标明本文标题和地址&#xff1a;本文标题&#xff1a;QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开 本文地址&#xff1a;http://techieliang.com/2017/12/685/ 文章…

工作182:表格渲染

<el-table :data"tableData" style"width: 100%" border> <!-- <el-table-column label"id" prop"1" align"center"></el-table-column>--><!--渲染账号名称--><el-table-column l…

Android 集成支付宝支付,支付宝支付2.0

成功起调支付宝支付 下载支付sdk复制到libs文件夹下并add as library&#xff1a;https://docs.open.alipay.com/54/104509 1、首先申请支付宝 企业账户 链接&#xff1a;https://memberprod.alipay.com/account/reg/enterpriseIndex.htm 备注&#xff1a;企业账户是以邮箱申…

docker centos node nginx

1、docker pull centos:centos8 2、进入容器 docker run -it centos:centos8 /bin/bash 3、安装git yum install -y git 4、安装nvm git clone https://github.com/creationix/nvm.git source nvm/nvm.sh 5、修改环境变量 vi ~/.bash_profile 加入source nvm/nvm.sh 更新 sour…

Appium——api常用函数

appium常用函数介绍&#xff1a;获取页面信息&#xff1a;1、 def get_current_activity(cls, driver):获取当前页面的activity:param driver::return:return driver.current_activity2、 def get_current_pagesource(cls, driver):获取当前页面源码:param driver::return: 返回…

android 微信支付,body为中文字符,签名错误

微信支付订单生产方法&#xff1a; /*** 根据您的订单信息 生成 微信产品支付订单信息*/private String createWeChatOrder() {StringBuffer xml new StringBuffer();try {String nonceStr genNonceStr();xml.append("</xml>");List<KeyValue> package…

使用Dockerfile部署vue项目

项目需要部署到甲方电脑上&#xff0c;使用docker是个不错的选择。 1、创建Dockerfile文件 # 设置基础镜像 FROM nginx:latest# 将dist文件中的内容复制到 /usr/share/nginx/html/ 这个目录下面 COPY dist/ /usr/share/nginx/html/ # 用本地的 default.conf 配置来替换nginx镜…

工作183:动态渲染数据 数据在数字字典里面

1接口调用 /*调用接口*/created() {/*动态渲染content_type接口*/getAction("/dict/list",{dict_code:"content_type"}).then(res>{this.content_typeres.data})/*动态渲染*/getAction("/dict/list",{dict_code:"resource_type"})…

cesium 修改 鼠标 样式

十字&#xff1a; viewer._container.style.cursor "crosshair"; 默认: viewer._container.style.cursor "default";

Android 集成微信支付详解

打包后才能起调支付 微信支付成功起调 微信skd下载&#xff1a;https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter11_1 签名APK下载&#xff1a;https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk 1、首先到微信.…

工作184:自定义事件

1子组件 mongo.vue <template><button click"eat">按钮</button> </template><script> export default {created() {this.$on("eat", function(fruit) {console.log("子组件接收自己发射的事件");});},methods:…

cesium label 显示隐藏到地底下

今天在写label的时候&#xff0c;发现高度为0时&#xff0c;label显示不全&#xff0c;影响用户体验&#xff0c;代码如下&#xff1a; window.labelEntity viewer.entities.add({label: {show: false,showBackground: true,font: "14px monospace",horizontalOrigi…

jq循环取数据 ,一直记不住,放到这

<!DOCTYPE html><html lang"en"><head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0, user-scalableno"> <title>首页</title> &l…

工作185:解决vue+el-element二级联动,选项选择后不显示的问题

一、问题描述 vue的二级联动可以采用v-if的方式去实现&#xff0c;也就是在第一级选项的值发生变化后&#xff0c;清空第二级选项所关联的model的值&#xff0c;并将第二级选项所取的变量数组变更。会产生的问题是&#xff0c;第二级选项的值有时候会出现值已改变但是页面上并不…

mongodb在aggregate lookup 进行分页查询,获得记录总数

直接上代码&#xff1a; const ones await InspectTaskUser.aggregate([{$facet: {paginatedResult: [{ $match: { user_id: ObjectId(_id) } },{ $skip: (page - 1) * size },{ $limit: size },{$lookup: {from: inspecttasks,localField: task_id,foreignField: _id,as: tas…

vmware安装centos问题

* 选择安装后&#xff0c;一直黑屏 重新启动电脑&#xff0c;在启动界面进入BIOS设置&#xff0c;找到Intel (R) Virtualization Technology&#xff0c;设置成Enabled&#xff0c;保存设置以后重新启动电脑&#xff0c;问题解决。转载于:https://www.cnblogs.com/gaotaozhaole…

工作186:实际案例解决vue+el-element二级联动,选项选择后不显示的问题

1组件 <el-form-item label"所属部门" :label-width"formLabelWidth"><select-form change"DepartmentList" v-model"form.department_id" /></el-form-item><!-- <el-form-item prop"business_module&…