Android RecyclerView小技巧

一 FlexboxLayoutManager

1. 无图言屌 先看看神奇的效果

2. build.gradle

buildscript {
    repositories {
        google()
        jcenter()
    }

    dependencies {
        classpath "com.android.tools.build:gradle:4.0.0"
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://jitpack.io" }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

3. app/build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"

    defaultConfig {
        applicationId "com.hy.flexboxlayoutmanager"
        minSdkVersion 21
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    implementation 'androidx.recyclerview:recyclerview:1.0.0'
    implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4'
    implementation 'com.google.android:flexbox:1.0.0'
    implementation 'com.ruffian.library:RWidgetHelper-AndroidX:0.0.8'
}

4. MainActivity

public class MainActivity extends AppCompatActivity implements OnItemClickListener {

    List<String> mList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mList.add("先帝创业未半而中道崩殂");
        mList.add("今天下三分");
        mList.add("益州疲弊");
        mList.add("此诚危急存亡之秋也");
        mList.add("然侍卫之臣不懈于内");
        mList.add("忠志之士忘身于外者");
        mList.add("盖追先帝之殊遇");
        mList.add("欲报之于陛下也");
        mList.add("诚宜开张圣听");
        mList.add("以光先帝遗德");
        mList.add("恢弘志士之气");
        mList.add("不宜妄自菲薄");
        mList.add("引喻失义");
        mList.add("以塞忠谏之路也");
        FlexboxLayoutManager manager = new FlexboxLayoutManager(this, FlexDirection.ROW, FlexWrap.WRAP);
        manager.setJustifyContent(JustifyContent.FLEX_START); //JustifyContent.CENTER=居中
        FlexboxAdapter adapter = new FlexboxAdapter(R.layout.item_flexbox, mList);
        adapter.setOnItemClickListener(this);
        RecyclerView recyclerView = findViewById(R.id.recycler);
        recyclerView.setLayoutManager(manager);
        recyclerView.setAdapter(adapter);
    }

    @Override
    public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
        Toast.makeText(this, mList.get(position), Toast.LENGTH_SHORT).show();
    }
}

5. activity_main

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="8dp"
        android:clipToPadding="false"
        android:scrollbars="none"
        android:overScrollMode="never" />
</RelativeLayout>

6. FlexboxAdapter

public class FlexboxAdapter extends BaseQuickAdapter<String, BaseViewHolder> {

    public FlexboxAdapter(int layoutResId, List data) {
        super(layoutResId, data);
    }

    @Override
    protected void convert(BaseViewHolder helper, String item) {
        helper.setText(R.id.text, item);
    }
}

7. item_flexbox

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <com.ruffian.library.widget.RTextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="8dp"
        android:paddingHorizontal="13dp"
        android:paddingVertical="3dp"
        android:singleLine="true"
        android:textColor="#FFF"
        app:background_normal="#0094FF"
        app:corner_radius="20dp" />
</FrameLayout>

二 SnapHelper

1. 无图言屌 先看看神奇的效果

2. build.gradle

buildscript {
    repositories {
        google()
        jcenter()
    }

    dependencies {
        classpath "com.android.tools.build:gradle:4.0.0"
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://jitpack.io" }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

3. app/build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"

    defaultConfig {
        applicationId "com.hy.snaphelper"
        minSdkVersion 21
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    implementation 'androidx.recyclerview:recyclerview:1.0.0'
    implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4'
    implementation 'com.yqritc:recyclerview-flexibledivider:1.4.0'
}

4. MainActivity

public class MainActivity extends AppCompatActivity implements OnItemClickListener {

    List<String> mList = new ArrayList<>();
    StaggeredGridLayoutManager mLayoutManager;
    boolean mScrolled; //之前是否进行过滚动

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mList.add("先帝创业未半而中道崩殂");
        mList.add("今天下三分");
        mList.add("益州疲弊");
        mList.add("此诚危急存亡之秋也");
        mList.add("然侍卫之臣不懈于内");
        mList.add("忠志之士忘身于外者");
        mList.add("盖追先帝之殊遇");
        mList.add("欲报之于陛下也");
        mList.add("诚宜开张圣听");
        mList.add("以光先帝遗德");
        mList.add("恢弘志士之气");
        mList.add("不宜妄自菲薄");
        mList.add("引喻失义");
        mList.add("以塞忠谏之路也");

        mLayoutManager = new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.HORIZONTAL);
        SnapAdapter adapter = new SnapAdapter(R.layout.item_snap, mList);
        adapter.setOnItemClickListener(this);
        RecyclerView recyclerView = findViewById(R.id.recycler);
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.addItemDecoration(new VerticalDividerItemDecoration
                .Builder(this)
                .size(dp2px(16))
                .colorResId(android.R.color.transparent)
                .build());
        recyclerView.setAdapter(adapter);
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == RecyclerView.SCROLL_STATE_IDLE && mScrolled) {
                    mScrolled = false;
                    int[] positions = mLayoutManager.findFirstCompletelyVisibleItemPositions(null);
                    int position = positions[0];
                    if (position >= 0) Toast.makeText(MainActivity.this, mList.get(position), Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (dx != 0 || dy != 0) {
                    mScrolled = true;
                }
            }
        });
        new LinearSnapHelper().attachToRecyclerView(recyclerView); //滚动多页
//        new PagerSnapHelper().attachToRecyclerView(recyclerView); //滚动单页
    }

    @Override
    public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
        Toast.makeText(this, mList.get(position), Toast.LENGTH_SHORT).show();
    }

    public int dp2px(final float dpValue) {
        float scale = Resources.getSystem().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}

5. activity_main

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:clipToPadding="false"
        android:scrollbars="none"
        android:overScrollMode="never" />
</RelativeLayout>

6. SnapAdapter

public class SnapAdapter extends BaseQuickAdapter<String, BaseViewHolder> {

    public SnapAdapter(int layoutResId, List data) {
        super(layoutResId, data);
    }

    @Override
    protected void convert(BaseViewHolder helper, String item) {
        helper.setText(R.id.text, item);
    }
}

7. item_snap

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/text"
        android:layout_width="300dp"
        android:layout_height="200dp"
        android:gravity="center"
        android:singleLine="true"
        android:textColor="#FFF"
        android:background="#0094ff" />
</FrameLayout>
原文地址:https://www.cnblogs.com/huangyi-427/p/14354190.html