[Andorid]使用BindingCollectionAdapter后recyclerView刷新闪烁的问题

5 篇文章 0 订阅
4 篇文章 0 订阅

最近在是使用一款mvvm框架,其中就用到了BindingCollectionAdapter绑定神器,有兴趣的朋友可以去看看,说实话我个人不是很喜欢这样的工具,因为业务复杂的情况下,开发和维护成本都很高,当然这是我个人见解。这个方案就是能支持databinding和recyclerview、listview的数据绑定,因为是首次使用,就遇到了之前没有遇到的刷新闪烁的问题。每次进入列表,刷新数据后,都会闪烁一下,个人猜想出现这种情况的可能性有几点:

  1. recyclerview本身的动画加载的问题
  2. 对应的适配器中没有复用viewholder,或者每次都是重复的刷新视图,导致每次都是重新构建view

于是通过不同的方式尝试修复,用了最简单的方案,可以看注释;希望对遇到相同问题的人有参考价值。

因为项目中用的是android的mvvm的架构,所以这里用到了databinding的方式(java代码)

    @BindingAdapter("bindNoAnimAdapter")
    public static void bindNoAnimAdapter(RecyclerView recyclerView,BaseBindingRecyclerViewAdapter adapter) {
        //防止重复刷新,需重写adapter的getItemId方法
        adapter.setHasStableIds(true);
        //直接清除动画
        recyclerView.setItemAnimator(null);
        //去除滑动阴影
        recyclerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
        recyclerView.setAdapter(adapter);
    }

adapter的代码如下

public class BaseBindingRecyclerViewAdapter<T> extends BindingRecyclerViewAdapter<T> {

    @Override
    public ViewDataBinding onCreateBinding(LayoutInflater inflater, @LayoutRes int layoutId, ViewGroup viewGroup) {
        ViewDataBinding binding = super.onCreateBinding(inflater, layoutId, viewGroup);
        return binding;
    }

    @Override
    public void onBindBinding(ViewDataBinding binding, int bindingVariable, @LayoutRes int layoutId, int position, T item) {
        super.onBindBinding(binding, bindingVariable, layoutId, position, item);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }
}

在xml里直接通过databinding的方式去设置即可;

<androidx.recyclerview.widget.RecyclerView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:overScrollMode="never"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@id/rl_search"
                    app:itemBinding="@{vm.itemBinding}"
                    app:items="@{vm.observableList}"
                    layoutManager="@{LayoutManagers.linear()}"
                    bindNoAnimAdapter="@{vm.adapter}"/>

要在 Android使用 ZXing 实现扫码,需要进行以下步骤: 1. 在 build.gradle 文件中添加以下依赖: ``` dependencies { implementation 'com.google.zxing:core:3.4.1' implementation 'com.journeyapps:zxing-android-embedded:3.5.0' } ``` 2. 在布局文件中添加一个 SurfaceView 用于预览摄像头捕获的图像,并添加一个按钮用于触发扫码操作: ``` <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <SurfaceView android:id="@+id/surface_view" android:layout_width="match_parent" android:layout_height="match_parent" /> <Button android:id="@+id/scan_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Scan" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" /> </RelativeLayout> ``` 3. 在 Activity 中实现扫码逻辑。首先,初始化 ZXing 的核心类 CaptureManager 和 ViewfinderView,然后在 onResume() 方法中启动摄像头预览,并在 onPause() 方法中停止预览。在按钮点击事件中触发扫码操作,并在 onActivityResult() 方法中获取扫码结果。 ``` public class ScanActivity extends AppCompatActivity implements OnScanListener { private CaptureManager captureManager; private SurfaceView surfaceView; private ViewfinderView viewfinderView; private Button scanButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scan); surfaceView = findViewById(R.id.surface_view); viewfinderView = findViewById(R.id.viewfinder_view); scanButton = findViewById(R.id.scan_button); captureManager = new CaptureManager(this, surfaceView, viewfinderView); captureManager.initializeFromIntent(getIntent(), savedInstanceState); captureManager.setOnScanListener(this); scanButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { captureManager.decode(); } }); } @Override protected void onResume() { super.onResume(); captureManager.onResume(); } @Override protected void onPause() { super.onPause(); captureManager.onPause(); } @Override protected void onDestroy() { super.onDestroy(); captureManager.onDestroy(); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); captureManager.onSaveInstanceState(outState); } @Override public void onScanResult(String result) { Toast.makeText(this, result, Toast.LENGTH_SHORT).show(); } @Override public void onScanError(Exception e) { Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show(); } @Override public void onScanCancel() { // Do nothing } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); captureManager.onActivityResult(requestCode, resultCode, data); } } ``` 以上就是使用 ZXing 实现扫码的基本步骤。你可以根据实际需求对代码进行修改和扩展。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值