欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

NestScrollView嵌套R(shí)ecyclerView實(shí)現(xiàn)淘寶首頁(yè)滑動(dòng)效果

 更新時(shí)間:2021年12月31日 10:31:42   作者:andr_gale  
這篇文章主要介紹了NestScrollView嵌套R(shí)ecyclerView實(shí)現(xiàn)淘寶首頁(yè)滑動(dòng)效果,主要實(shí)現(xiàn)淘寶首頁(yè)嵌套滑動(dòng),中間tab吸頂效果,以及介紹NestScrollView嵌套R(shí)ecyclerView處理滑動(dòng)沖突的方法,需要的朋友可以參考下

一.概述

本文主要實(shí)現(xiàn)淘寶首頁(yè)嵌套滑動(dòng),中間tab吸頂效果,以及介紹NestScrollView嵌套R(shí)ecyclerView處理滑動(dòng)沖突的方法,淘寶首頁(yè)的效果圖如下:

二.開(kāi)搞

首先我們通過(guò)一張圖來(lái)分析下頁(yè)面的布局結(jié)構(gòu):

先把最基礎(chǔ)的頁(yè)面搭出來(lái),禁用Recycler滑動(dòng)只需要重寫(xiě)onInterceptTouchEvent、onTouchEvent返回值都設(shè)為false即可:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activiy.ViewPagerActivity"
    android:background="#f2f2f2">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <com.aykj.nestscrolldemo.widget.NoScrollRecyclerView
            android:id="@+id/top_recycler_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <View
                android:layout_width="match_parent"
                android:layout_height="1px"
                android:background="#e0e0e0"/>

            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tab_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <View
                android:layout_width="match_parent"
                android:layout_height="1px"
                android:background="#e0e0e0"/>

            <androidx.viewpager.widget.ViewPager
                android:id="@+id/view_pager"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>

        </LinearLayout>

    </LinearLayout>

</ScrollView>
public class ViewPagerActivity extends AppCompatActivity {

    private List<String> topDatas = new ArrayList<>();
    private List<String> tabTitles = new ArrayList<>();
    ActivityViewPagerBinding viewBinding;
    private RecyclerAdapter topAdapter;
    private DividerItemDecoration divider;
    private TabFragmentAdapter pagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        viewBinding = ActivityViewPagerBinding.inflate(LayoutInflater.from(this));
        setContentView(viewBinding.getRoot());

        initDatas();
        initView();
    }

    private void initDatas() {
        topDatas.clear();
        for(int i=0; i<5; i++) {
            topDatas.add("top item " + (i + 1));
        }

        tabTitles.clear();
        tabTitles.add("tab1");
        tabTitles.add("tab2");
        tabTitles.add("tab3");
    }

    private void initView() {
        //init topRecycler
        divider = new DividerItemDecoration(this, LinearLayout.VERTICAL);
        divider.setDrawable(new ColorDrawable(Color.parseColor("#ffe0e0e0")));
        viewBinding.topRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        viewBinding.topRecyclerView.addItemDecoration(divider);
        topAdapter = new RecyclerAdapter(this, topDatas);
        viewBinding.topRecyclerView.setAdapter(topAdapter);

        //initTabs with ViewPager
        pagerAdapter = new TabFragmentAdapter(getSupportFragmentManager(), tabTitles);
        viewBinding.viewPager.setAdapter(pagerAdapter);
        viewBinding.tabView.setupWithViewPager(viewBinding.viewPager);
        viewBinding.tabView.setTabMode(TabLayout.MODE_FIXED);
    }
}

可以看到ViewPager沒(méi)有正常顯示出來(lái),這個(gè)時(shí)候可以重寫(xiě)ViewPager的onMeasure,重新測(cè)量ViewPager的寬高。也可以換用ViewPager2

public class CustomViewPager extends ViewPager {
  	...
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //重寫(xiě)ViewPager的onMeasure
        int width = 0;
        int height = 0;
        for(int i=0; i<getChildCount(); i++) {
            View childView = getChildAt(0);
            measureChild(childView, widthMeasureSpec, heightMeasureSpec);
            width = Math.max(width, childView.getMeasuredWidth());
            height = Math.max(height, childView.getMeasuredHeight());
        }

        height += getPaddingTop() + getPaddingBottom();
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

從上面的效果圖可以看到,ViewPager能正常顯示出來(lái)了,但是在RecyclerView上滑動(dòng)的時(shí)候發(fā)現(xiàn),RecyclerView滑動(dòng)完了之后,ScrollView才會(huì)滑動(dòng),并且ScrollView只滑動(dòng)了一小段距離,這是因?yàn)槭紫萐crollView是不支持嵌套滑動(dòng)的

ScrollView內(nèi)部的第一個(gè)子View中所有子View的高度 = 頂部的RecyclerView高度 + TabLayout高度 + 底部RecyclerView中所有可見(jiàn)Item的高度

這個(gè)高度只比ScrollView的高度大一點(diǎn)點(diǎn)導(dǎo)致的。為了實(shí)現(xiàn)嵌套滑動(dòng)需要使用NestedScrollView,接下來(lái)把ScrollView替換成NestedScrollView:

整個(gè)頁(yè)面可以滑完,看起來(lái)就像是兩個(gè)Scroll被合并成一個(gè)了,如果單單只是實(shí)現(xiàn)上面的界面效果,我們完全可以使用一個(gè)RecyclerView即可,但是Tab沒(méi)有吸頂,這是因?yàn)?

ScrollView內(nèi)部的第一個(gè)子View中所有子View的高度 = 頂部的RecyclerView高度 + TabLayout高度 + 底部RecyclerView中所有Item的高度

要實(shí)現(xiàn)Tab吸頂,只需要重寫(xiě)NestedScrollView的onMeasue方法,將TabLayout的高度和ViewPager的高度之和設(shè)置為NestedScrollView的高度:

public class StickyScrollLayout extends NestedScrollView {
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        int count = getChildCount();
        if(count == 1) {
            View firstChild = getChildAt(0);
            if(firstChild != null && firstChild instanceof ViewGroup) {
                int childCount = ((ViewGroup) firstChild).getChildCount();
                if(childCount > 1) {
                    topView = ((ViewGroup) firstChild).getChildAt(0);
                    contentView = ((ViewGroup) firstChild).getChildAt(1);
                }
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        if(contentView != null) {
            ViewGroup.LayoutParams contentLayoutParams = contentView.getLayoutParams();
            contentLayoutParams.height = getMeasuredHeight();
            contentView.setLayoutParams(contentLayoutParams);
        }
    }
}

此時(shí)TabLayout可以吸頂了

三.處理嵌套滑動(dòng)

從上圖中可以看出,當(dāng)我們?cè)赗ecyclerView上向上滑動(dòng)時(shí),需要等RecyclerView滑動(dòng)完,外部的NestedScrollView才開(kāi)始滑動(dòng),而我們希望NestedScrollView中頂部的RecyclerView滑完之后,底部的RecyclerView才開(kāi)始滑動(dòng),這是為什么呢?

查看NestedScrollView和RecyclerView的源碼,可以知道NestedScrollView和RecyclerView分別實(shí)現(xiàn)了NestedScrollingParent3,NestedScrollingChild3接口,分別用來(lái)表示嵌套滑動(dòng)的父View、嵌套滑動(dòng)的子View,當(dāng)我們的手指在RecyclerView上滑動(dòng)時(shí),滑動(dòng)事件會(huì)從上往下分發(fā)至RecyclerView的onTouchEvent中,RecyclerView會(huì)依次響應(yīng)ACTION_DOWN、ACTION_MOVE、ACTION_UP

RecyclerView在處理ACTION_DOWN時(shí)的關(guān)鍵代碼如下:

public boolean onTouchEvent(MotionEvent e) {
  switch (action) {
    case MotionEvent.ACTION_DOWN: {
      if (canScrollHorizontally) {
        nestedScrollAxis |= ViewCompat.SCROLL_AXIS_HORIZONTAL;
      }
      if (canScrollVertically) {
        nestedScrollAxis |= ViewCompat.SCROLL_AXIS_VERTICAL;
      }
      startNestedScroll(nestedScrollAxis, TYPE_TOUCH);
    } break;
  }
  return true;
}

當(dāng)手指按下屏幕時(shí)會(huì)調(diào)用其作為NestedScrollingChild的實(shí)現(xiàn)方法startNestedScroll,在startNestedScroll的具體實(shí)現(xiàn)中,會(huì)一級(jí)一級(jí)的往上查找是否有NestedScrollingParent,如果有,會(huì)調(diào)用NestedScrollingParent的onStartNestedScroll方法通知它我即將要開(kāi)始滑動(dòng)了,然后NestedScrollingParent會(huì)調(diào)用onNestedScrollAccepted繼續(xù)傳遞給上層的NestedScrollingParent,此處的NestedScrollingParent整好由NestedScrollView來(lái)充當(dāng),而NestedScrollView的上層已經(jīng)找不到NestedScrollingParent了,時(shí)間傳給NestedScrollView之后就中斷了。

緊接著處理一系列的ACTION_MOVE:

public boolean onTouchEvent(MotionEvent e) {
  switch (action) {
    case MotionEvent.ACTION_MOVE: {
      if (dispatchNestedPreScroll(
        canScrollHorizontally ? dx : 0,
        canScrollVertically ? dy : 0,
        mReusableIntPair, mScrollOffset, TYPE_TOUCH
      )) {
        dx -= mReusableIntPair[0];
        dy -= mReusableIntPair[1];
        // Updated the nested offsets
        mNestedOffsets[0] += mScrollOffset[0];
        mNestedOffsets[1] += mScrollOffset[1];
        // Scroll has initiated, prevent parents from intercepting
        getParent().requestDisallowInterceptTouchEvent(true);
      }
      
      if (scrollByInternal(
        canScrollHorizontally ? dx : 0,
        canScrollVertically ? dy : 0,
        e)) {
        getParent().requestDisallowInterceptTouchEvent(true);
      }
    } break;
  }
  return true;
}

RecyclerView接收到ACTION_MOVE后,首先會(huì)調(diào)用其作為NestedScrollingChild的實(shí)現(xiàn)方法dispatchNestedPreScroll,在dispatchNestedPreScroll的具體實(shí)現(xiàn)中,會(huì)一級(jí)一級(jí)的往上查找是否有NestedScrollingParent,如果有,會(huì)調(diào)用NestedScrollingParent的dispatchNestedPreScroll,緊接著調(diào)用NestedScrollView的onNestedPreScroll,來(lái)告訴NestedScrollView我即將要滑動(dòng) xxx 距離,你需不需要滑動(dòng),在NestedScrollView的onNestedPreScroll方法中并不會(huì)去響應(yīng)滑動(dòng),又會(huì)把自己作為一個(gè)NestedScrollingChild,把事件繼續(xù)往上傳遞,而在NestedScrollView的上層已經(jīng)沒(méi)有可以處理嵌套滑動(dòng)的NestedScrollingParent了

@Override
public void onNestedPreScroll(@NonNull View target, int dx, int dy, @NonNull int[] consumed,
int type) {
	dispatchNestedPreScroll(dx, dy, consumed, null, type);
}

具體的事件傳遞流程如下圖:

因此我們可以重寫(xiě)NestedScrollView的onNestedPreScroll方法來(lái)使NestedScrollView滑動(dòng)

public class StickyNestedScrollLayout extends NestedScrollView {
  
  	@Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        int count = getChildCount();
        if(count == 1) {
            View firstChild = getChildAt(0);
            if(firstChild != null && firstChild instanceof ViewGroup) {
                int childCount = ((ViewGroup) firstChild).getChildCount();
                if(childCount > 1) {
                    topView = ((ViewGroup) firstChild).getChildAt(0);
                    contentView = ((ViewGroup) firstChild).getChildAt(1);
                }
            }
        }
    }
  
    @Override
    public void onNestedPreScroll(@NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {
        boolean topIsShow = getScrollY() >=0 && getScrollY() < topView.getHeight();
        if(topIsShow) {
            scrollBy(0, dy);
        } else {
          super.onNestedPreScroll(target, dx, dy, consumed, type);
        }
    }
}

此時(shí)NestedScrollView能滑動(dòng)了,但是NestedScrollView滑動(dòng)的同時(shí),RecyclerView也會(huì)跟著滑動(dòng),這是為什么呢?

在RecyclerView的dispatchNestedPreScroll方法具體實(shí)現(xiàn)中,有這樣一段代碼

public boolean dispatchNestedPreScroll(int dx, int dy, @Nullable int[] consumed,
            @Nullable int[] offsetInWindow, @NestedScrollType int type) {
  if (isNestedScrollingEnabled()) {
      consumed[0] = 0;
      consumed[1] = 0;
      ViewParentCompat.onNestedPreScroll(parent, mView, dx, dy, consumed, type);
    	//consumed[0]、consumed[1]的值仍為0
      return consumed[0] != 0 || consumed[1] != 0;//返回false
    }
  }
  return false;
}

再結(jié)合RecyclerView的ACTION_MOVE來(lái)看:

public boolean onTouchEvent(MotionEvent e) {
  switch (action) {
    case MotionEvent.ACTION_MOVE: {
      if (dispatchNestedPreScroll(
        canScrollHorizontally ? dx : 0,
        canScrollVertically ? dy : 0,
        mReusableIntPair, mScrollOffset, TYPE_TOUCH
      )) {
        //dispatchNestedPreScroll返回了false,此處的if語(yǔ)句不會(huì)執(zhí)行,因此RecyclerView也會(huì)滑動(dòng)
        dx -= mReusableIntPair[0];
        dy -= mReusableIntPair[1];
        // Updated the nested offsets
        mNestedOffsets[0] += mScrollOffset[0];
        mNestedOffsets[1] += mScrollOffset[1];
        // Scroll has initiated, prevent parents from intercepting
        getParent().requestDisallowInterceptTouchEvent(true);
      }
      
      if (scrollByInternal(
        canScrollHorizontally ? dx : 0,
        canScrollVertically ? dy : 0,
        e)) {
        getParent().requestDisallowInterceptTouchEvent(true);
      }
    } break;
  }
  return true;
}

因此,我們,在NestedScrollView的onNestedPreScroll方法中,處理完滑動(dòng)后,通過(guò)consumed告訴RecyclerView我滑動(dòng)了多少,這樣

RecyclerView會(huì)重新設(shè)置dx、dy的值,因此RecyclerView就不會(huì)跟著滑動(dòng)了

public class StickyNestedScrollLayout extends NestedScrollView {
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        int count = getChildCount();
        if(count == 1) {
            View firstChild = getChildAt(0);
            if(firstChild != null && firstChild instanceof ViewGroup) {
                int childCount = ((ViewGroup) firstChild).getChildCount();
                if(childCount > 1) {
                    topView = ((ViewGroup) firstChild).getChildAt(0);
                    contentView = ((ViewGroup) firstChild).getChildAt(1);
                }
            }
        }
    }

    @Override
    public void onNestedPreScroll(@NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {
        boolean topIsShow = getScrollY() >=0 && getScrollY() < topView.getHeight();
        if(topIsShow) {
            scrollBy(0, dy);
            //告訴RecyclerView,我滑動(dòng)了多少距離
            consumed[1] = dy;
        } else {
            super.onNestedPreScroll(target, dx, dy, consumed, type);
        }
    }
}

四.實(shí)現(xiàn)慣性滑動(dòng)

實(shí)現(xiàn)思路:

記錄父控件慣性滑動(dòng)的速度判斷NestedScrollView是否滾動(dòng)到底部,若滾動(dòng)到底部,判斷子控件是否需要繼續(xù)滾動(dòng)滾動(dòng)將慣性滑動(dòng)的速度轉(zhuǎn)化成距離,計(jì)算子控件應(yīng)滑的距離 = 慣性距離 - 父控件已滑動(dòng)距離,并將子控件應(yīng)滑的距離轉(zhuǎn)化成速度交給子控件進(jìn)行慣性滑動(dòng)

1.記錄父控件慣性滑動(dòng)的速度

public void fling(int velocityY) {
  super.fling(velocityY);
  if (velocityY <= 0) {
  	mVelocityY = 0;
  } else {
  	mVelocityY = velocityY;
  }
}

2.判斷NestedScrollView是否滾動(dòng)到底部,若滾動(dòng)到底部,判斷子控件是否需要繼續(xù)滾動(dòng)

@Override
protected void onScrollChanged(int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
  super.onScrollChanged(scrollX, scrollY, oldScrollX, oldScrollY);
  /*
         * scrollY == 0 即還未滾動(dòng)
         * scrollY == getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight()即滾動(dòng)到底部了
         */
  //判斷NestedScrollView是否滾動(dòng)到底部,若滾動(dòng)到底部,判斷子控件是否需要繼續(xù)滾動(dòng)
  if (scrollY == getChildAt(0).getMeasuredHeight() - this.getMeasuredHeight()) {
    dispatchChildFling();
  }
  //累計(jì)自身滾動(dòng)的距離
  mConsumedY += scrollY - oldScrollY;
}

3.將慣性滑動(dòng)的速度轉(zhuǎn)化成距離,計(jì)算子控件應(yīng)滑的距離 = 慣性距離 - 父控件已滑動(dòng)距離,并將子控件應(yīng)滑的距離轉(zhuǎn)化成速度交給子控件進(jìn)行慣性滑動(dòng)

private void dispatchChildFling() {
    if(mFlingHelper == null) {
      mFlingHelper = new FlingHelper(getContext());
    }
    if (mVelocityY != 0) {
        //將慣性滑動(dòng)速度轉(zhuǎn)化成距離
        double distance = mFlingHelper.getSplineFlingDistance(mVelocityY);
        //計(jì)算子控件應(yīng)該滑動(dòng)的距離 = 慣性滑動(dòng)距離 - 已滑距離
        if (distance > mConsumedY) {
            RecyclerView recyclerView = getChildRecyclerView(mContentView);
            if (recyclerView != null) {
                //將剩余滑動(dòng)距離轉(zhuǎn)化成速度交給子控件進(jìn)行慣性滑動(dòng)
                int velocityY = mFlingHelper.getVelocityByDistance(distance - mConsumedY);
                recyclerView.fling(0, velocityY);
            }
        }
    }

    mConsumedY = 0;
    mVelocityY = 0;
}

//遞歸獲取子控件RecyclerView
private RecyclerView getChildRecyclerView(ViewGroup viewGroup) {
  for (int i = 0; i < viewGroup.getChildCount(); i++) {
    View view = viewGroup.getChildAt(i);
    if (view instanceof RecyclerView && Objects.requireNonNull(((RecyclerView) view).getLayoutManager()).canScrollVertically()) {
      return (RecyclerView) view;
    } else if (viewGroup.getChildAt(i) instanceof ViewGroup) {
      RecyclerView childRecyclerView = getChildRecyclerView((ViewGroup) viewGroup.getChildAt(i));
      if (childRecyclerView != null && Objects.requireNonNull((childRecyclerView).getLayoutManager()).canScrollVertically()) {
        return childRecyclerView;
      }
    }
  }
  return null;
}

到此這篇關(guān)于NestScrollView嵌套R(shí)ecyclerView實(shí)現(xiàn)淘寶首頁(yè)滑動(dòng)效果的文章就介紹到這了,更多相關(guān)NestScrollView嵌套R(shí)ecyclerView內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android 程序申請(qǐng)權(quán)限注意事項(xiàng)

    Android 程序申請(qǐng)權(quán)限注意事項(xiàng)

    本主要介紹Android 程序申請(qǐng)權(quán)限注意事項(xiàng),這里整理了相關(guān)資料,并詳細(xì)說(shuō)明如何避免開(kāi)發(fā)的程序支持設(shè)備減少,有需要的小伙伴可以參考下
    2016-09-09
  • Android獲取SDcard目錄及創(chuàng)建文件夾的方法

    Android獲取SDcard目錄及創(chuàng)建文件夾的方法

    今天小編就為大家分享一篇Android獲取SDcard目錄及創(chuàng)建文件夾的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • Android開(kāi)發(fā)之完成登陸界面的數(shù)據(jù)保存回顯操作實(shí)例

    Android開(kāi)發(fā)之完成登陸界面的數(shù)據(jù)保存回顯操作實(shí)例

    這篇文章主要介紹了Android開(kāi)發(fā)之完成登陸界面的數(shù)據(jù)保存回顯操作實(shí)現(xiàn)方法,結(jié)合完整實(shí)例形式較為詳細(xì)的分析了Android針對(duì)登錄數(shù)據(jù)的保存及回顯操作技巧,需要的朋友可以參考下
    2015-12-12
  • Android Studio中生成aar文件及本地方式使用aar文件的方法

    Android Studio中生成aar文件及本地方式使用aar文件的方法

    這篇文章給大家講解Android Studio中生成aar文件以及本地方式使用aar文件的方法,也就是說(shuō) *.jar 與 *.aar 的生成與*.aar導(dǎo)入項(xiàng)目方法,本文給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2017-12-12
  • 深入Android SQLite 事務(wù)處理詳解

    深入Android SQLite 事務(wù)處理詳解

    本篇文章是對(duì)Android中SQLite 事務(wù)處理進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下
    2013-05-05
  • RecyclerView實(shí)現(xiàn)查看更多及收起

    RecyclerView實(shí)現(xiàn)查看更多及收起

    這篇文章主要為大家詳細(xì)介紹了RecyclerView實(shí)現(xiàn)查看更多及收起,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • Flutter實(shí)現(xiàn)自定義下拉選擇框的示例詳解

    Flutter實(shí)現(xiàn)自定義下拉選擇框的示例詳解

    在一些列表頁(yè)面中,我們經(jīng)常會(huì)有上方篩選項(xiàng)的的需求,點(diǎn)擊出現(xiàn)一個(gè)下拉菜單,而在Flutter中,并沒(méi)有現(xiàn)成的這樣的組件,所以最好我們可以自己做一個(gè)。本文將利用Flutter實(shí)現(xiàn)自定義下拉選擇框,需要的可以參考一下
    2022-04-04
  • Android下hook點(diǎn)擊事件的示例

    Android下hook點(diǎn)擊事件的示例

    這篇文章主要介紹了Android下hook點(diǎn)擊事件的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • Jetpack?Compose?實(shí)現(xiàn)一個(gè)圖片選擇框架功能

    Jetpack?Compose?實(shí)現(xiàn)一個(gè)圖片選擇框架功能

    這篇文章主要介紹了Jetpack?Compose?實(shí)現(xiàn)一個(gè)圖片選擇框架,本文通過(guò)實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • 在Android中高效的加載大圖的方法示例

    在Android中高效的加載大圖的方法示例

    本篇文章主要介紹了在Android中高效的加載大圖的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06

最新評(píng)論