RecyclerView里notifyItemRemoved的坑

RecyclerView很多时候是展示静态的数据,并不会有删除的操作,讲到RecyclerView时,会提到它提供了一个很好的展现删除操作动画的函数,代码片段一般是这样的 @Override public void onBindViewHolder(final CommonViewHolder holder, final int position) { holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { contentList.remove(position); notifyItemRemoved(position); } }); } 这样写的话,很快会产生数据删除错乱和超出索引异常导致崩溃。 原因是函数里面的传入的参数position,它是在进行onBind操作时确定的,在删除单项后,已经出现在画面里的项不会再有调用onBind机会,这样它保留的position一直是未进行删除操作前的postion值。 对于尚未进入画面的单项来说,它会使用新的position值,这个值是正确的,如果在单项里加上下面的代码 holder.textView.setText(contentList.get(position) + "#" + String.valueOf(position)); 在删除第一屏的一项后,向上滚动,会发现新滚上来的一行和它上面的一行的textview显示是一样的。 解决办法也很简单 先remove,再notifyItemRemoved, 最后再notifyItemRangeChanged remove:把数据从list中remove掉, notifyItemRemoved:显示动画效果 notifyItemRangeChanged:对于被删掉的位置及其后range大小范围内的view进行重新onBindViewHolder

八月 14, 2018 · 1 分钟 · LengYue

在视频列表中,实现对当前显示的视频的自动播放、跟踪、暂停

简单说一下原理,当RecycleView处于停滞状态的时候,通过findFirstVisibleItemPosition() findLastVisibleItemPosition()取出所有可视的Item,通过recyclerView.getChildAt(i)取出相应的Item的布局recyclerView.getChildAt(0)取出的永远是当前可见的第一个,在对所有的可见的item中的视频播放控件的可见区域作对比这里是通过Rect作比较的,如果有多个完整可见的视频播放控件,则可以比较视频播放控件是否在屏幕中央,距离屏幕中央的距离确认。 /** * Created by LengYue on 2017/9/16. */ public class VideoPlayListener extends RecyclerView.OnScrollListener { private static final String TAG = "VideoPlayListener"; private ArrayList<View> mViews; private IDataType mDataType; public VideoPlayListener(IDataType mDataType) { super(); mViews = new ArrayList<>(); this.mDataType = mDataType; } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); LinearLayoutManager manager = (LinearLayoutManager) recyclerView....

八月 14, 2018 · 2 分钟 · LengYue

适配三星Galaxy S8及S8+

高达84%的屏幕占比为Galaxy S8及S8+在游戏娱乐、观看视频时带来深度沉浸式视觉体验。但是与此同时S8却有着一个奇葩的屏幕比例:18.5比9,屏幕分辨率:2960×1440。通常我们在开发过程中android的标准设计图为1920×1080,ios为1334×750,默认采用16比9的比例来设计效果图。 这是未适配的网易新闻 其实解决APP显示问题,除了第三方应用自行适配S8之外,S8自己也可以进行调节,S8有一个功能叫做“全屏应用程序” 打开全屏应用之后,效果显而易见: 下面我们以开发者的身份去分析下这个问题,究其根本这个适配不过是个显示的问题,我们只需要让APP充满全屏就可以,所以我做了如下尝试: 1:给Activity设置各种noTitlebar,FullScreen,不起作用; 2:替换各种style样式,不起作用; 3:修改targetSdkVersion, compileSdkVersion为高版本,依然不起作用。 通过观察发现,凡是完美适配了18.5比9屏幕的App,在系统中已经默认是全屏应用程序了,选择框灰掉无法点击。 而没有做好适配的App默认是没有打开全屏应用的,用户可以自行随意选择打开或者关闭 所以判断系统应该是通过检测某个属性或者权限来区分当前App是否做好了适配。最后我们找到了"android.max_aspect"这个属性。 开发者只需在App的AndroidManifest.xml文件 中添加如下代码: <meta-data android:name="android.max_aspect" android:value="2.1" /> 对只要这一行代码就搞定三星S8的适配,所以前面都是废话,你要的代码就这一行 Android 标准接口中,支持应用声明其支持的最大屏幕高宽比(maximum aspect ratio)。具体声明如下,其中的 ratio_float 被定义为是高除以宽,以16:9为例,ratio_float = 16/9 = 1.778 (18.5:9则为2.056)。 若开发者没有声明该属性,ratio_float 的默认值为1.86,小于2.056,因此这类应用在三星S8上,默认不会全屏显示,屏幕两边会留黑。

八月 14, 2018 · 1 分钟 · LengYue

Centos7 软件源安装Python3.6环境

之前一直是编译安装,装的多了就感觉麻烦,写个脚本还要上传。。。 随意找了一下,发现软件源里有Python。记录一下 配置好Python3.6和pip3 安装EPEL和IUS软件源 yum install epel-release -y yum install https://centos7.iuscommunity.org/ius-release.rpm -y 安装Python3.6 yum install python36u -y 创建python3连接符 ln -s /bin/python3.6 /bin/python3 安装pip3 yum install python36u-pip -y 创建pip3链接符 ln -s /bin/pip3.6 /bin/pip3

七月 17, 2018 · 1 分钟 · LengYue

unable to connect to 5555: connection refused

I had the same issue since the android 6 upgrading. I noticed that for some reason the device is playing “hard to get” when you try to contact it over WIFI. Try these following steps: Make sure that Aggressive Wi-Fi to Cellular handover under Networking section in the device’s developer options is turned off. ping continuously from your pc to the device to make sure it’s not in network idle mode ping -t 192....

七月 17, 2018 · 1 分钟 · LengYue

Android 7.0适配-应用之间共享文件(FileProvider)

一、前言 Android 7.0强制启用了被称作 StrictMode的策略,带来的影响就是你的App对外无法暴露file://类型的URI了。 如果你使用Intent携带这样的URI去打开外部App(比如:打开系统相机拍照),那么会抛出FileUriExposedException异常。 官方给出解决这个问题的方案,就是使用FileProvider: 这是常见的打开系统相机拍照的代码,拍照成功后,照片会存储在picFile文件中。 这段代码在Android 7.0之前是没有任何问题的(奇葩情况忽略~),但是如果你尝试在7.0的系统上运行(可以用模拟器测试,我也没真机~),会抛出文章开头提到的FileUriExposedException异常。 既然官方推荐使用FileProvider来解决此问题,我们就来看下如何使用吧~ ...

七月 8, 2018 · 2 分钟 · LengYue

Java里如何实现线程间通信?

下面我从几个例子作为切入点来讲解下 Java 里有哪些方法来实现线程间通信。 如何让两个线程依次执行? 那如何让两个线程按照指定方式有序交叉运行呢? 四个线程 A B C D,其中 D 要等到 A B C 全执行完毕后才执行,而且 A B C 是同步运行的 三个运动员各自准备,等到三个人都准备好后,再一起跑 子线程完成某件任务后,把得到的结果回传给主线程 如何让两个线程依次执行? 假设有两个线程,一个是线程 A,另一个是线程 B,两个线程分别依次打印 1-3 三个数字即可。我们来看下代码: private static void demo1() { Thread A = new Thread(new Runnable() { @Override public void run() { printNumber("A"); } }); Thread B = new Thread(new Runnable() { @Override public void run() { printNumber("B"); } }); A....

七月 8, 2018 · 6 分钟 · LengYue

RecyclerView与AppBarLayout 组合的下拉刷新、滑动不顺畅的问题

滑动有粘性 滑动有粘性,需要在拉一次才能生效,解决办法: mRecylerview.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState == RecyclerView.SCROLL_STATE_IDLE) { int firstVisiblePosition = layoutManager.findFirstCompletelyVisibleItemPosition(); if (firstVisiblePosition == 0) { mAppbar.setExpanded(true, true); } } } }); 下拉刷新 如果appBarLayout中有折叠控件 CollapsingToolbarLayout 或者其他一些控件 在滚动的时候进行判断和刷新事件处理: 第一步:设置appBarLayout的监听: if (appBarLayout != null) appBarLayout.addOnOffsetChangedListener(this); 第二部: @Override public void onOffsetChanged(AppBarLayout appBarLayout, int i) { super.onOffsetChanged(appBarLayout, i); if (srlLayout == null) return; srlLayout....

七月 8, 2018 · 1 分钟 · LengYue