授權原文:https://mp.weixin.qq.com/s/X6lnv2lkyUq72Lw8mdsIjg
Android相容性最佳化-Android M以下相容ScrollView.setOnScrollChangeListener() 方案
崩潰日誌:java.lang.NoClassDefFoundError12-08 13:47:58.781 8872 8872 W dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x41a72ce0)6512-08 13:47:58.781 8872 8872 W dalvikvm: threadid=1: uncaught exception occurred6612-08 13:47:58.781 8872 8872 W System.err: java.lang.NoClassDefFoundError: com.pxwx.curricula.CurriculaFragment$c6712-08 13:47:58.782 8872 8872 W System.err: at com.pxwx.curricula.CurriculaFragment.initView()6812-08 13:47:58.782 8872 8872 W System.err: at com.pxwx.curricula.CurriculaFragment.onViewCreated()6912-08 13:47:58.782 8872 8872 W System.err: at androidx.fragment.app.FragmentStateManager.createView()
丟擲異常資訊:
java.lang.NoClassDefFoundError
定位出錯位置initView方法:針對ScrollView.setOnScrollChangeListener()方法添加了如下註解
@RequiresApi(api = Build.VERSION_CODES.M)
以上註解表示註解目標只能夠在指定的版本API及以上執行,消除高版本Api在低版本SDK上的報錯。
注:慎用@RequiresApi等註解消除高版本Api在低版本SDK上的報錯,容易出現版本相容問題
@RequiresApi(api = Build.VERSION_CODES.M)private void initView() { //初始化滑動聯動toolbar nsv.setOnScrollChangeListener(new View.OnScrollChangeListener() { @Override public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { if (scrollY < SCROLL_DISTANCE) {//隱藏toolbar if (scrollY < SCROLL_MINHEIGHT){ toolbar.set(View.GONE); toolbarTitle.set(View.GONE); toolbarTitleAlpha.set(0f); }else{ toolbar.set(View.VISIBLE); //標題欄的漸變 toolbarBackColor.set(changeAlpha(UIUtils.getColor(R.color.white) , scrollY / SCROLL_DISTANCE)); toolbarTitleAlpha.set(scrollY / SCROLL_DISTANCE); toolbarTitle.set(View.VISIBLE); } }else{ toolbar.set(View.VISIBLE); toolbarTitle.set(View.VISIBLE); toolbarTitleAlpha.set(1.0f); toolbarBackColor.set(UIUtils.getColor(R.color.white)); } } });
根據如上分析,導致 java.lang.NoClassDefFoundError異常是因為執行在了sdk低於23的版本上手機上導致的。
解決方法:如下解決ScrollView.setOnScrollChangeListener() 在23以下相容可用;
可以透過實現NestedScrollView並複寫它的onScrollChanged方法自定義監聽,具體程式碼如下:
/** * 修復setOnScrollChangeListener不相容M以下版本 */ //1、定義NormalScorllVIew並整合NestedScrollViewpublic class NormalScorllVIew extends NestedScrollView { private OnScrollChanged mOnScrollChanged; public NormalScorllVIew(@NonNull Context context) { super(context); } public NormalScorllVIew(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public NormalScorllVIew(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } //2、複寫onScrollChanged方法 @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); //5、透過介面執行自身的滑動監聽 if (mOnScrollChanged != null) mOnScrollChanged.onScroll(l, t, oldl, oldt); } //4、給義NormalScorllVIew新增介面監聽 public void setOnScrollChanged(OnScrollChanged onScrollChanged){ this.mOnScrollChanged = onScrollChanged; } //3、定義自定義介面,暴露onScroll方法 public interface OnScrollChanged{ void onScroll(int l, int t, int oldl, int oldt); }}
外面實現自定義的介面,自定義ScrollView設定介面監聽,複寫onScroll方法,監聽滑動
//1、實現自定義的介面xxx implements NormalScorllVIew.OnScrollChanged//2自定義ScrollView設定介面監聽nsv.setOnScrollChanged(this);//3、複寫onScroll方法@Overridepublic void onScroll(int scrollX, int scrollY, int oldScrollX, int oldScrollY) { //4、監聽滑動 if (scrollY < SCROLL_DISTANCE) {//隱藏toolbar if (scrollY < SCROLL_MINHEIGHT){ toolbar.set(View.GONE); toolbarTitle.set(View.GONE); toolbarTitleAlpha.set(0f); }else{ toolbar.set(View.VISIBLE); //標題欄的漸變 toolbarBackColor.set(viewModel.changeAlpha(UIUtils.getColor(R.color.white) , scrollY / SCROLL_DISTANCE)); toolbarTitleAlpha.set(scrollY / SCROLL_DISTANCE); toolbarTitle.set(View.VISIBLE); } }else{ toolbar.set(View.VISIBLE); toolbarTitle.set(View.VISIBLE); toolbarTitleAlpha.set(1.0f); toolbarBackColor.set(UIUtils.getColor(R.color.white)); }}
後臺私信回覆 1024 免費領取 SpringCloud、SpringBoot,微信小程式、Java面試、資料結構、演算法等全套影片資料。
最新評論