当前位置:   article > 正文

RecyclerView 的简单使用 -- (横向/纵向)列表、网格、瀑布流的实现_android recyclerview实现横向瀑布流布局

android recyclerview实现横向瀑布流布局

代码实现

RecyclerViewActivity.java

public class RecyclerViewActivity extends BaseActivity {

    private RecyclerView recyclerView;
    private MyRecyclerViewAdapter adapter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_recyclerview);

        recyclerView = findViewById(R.id.recyclerview);

        initRecyclerView();
    }

    /**
     * 初始化 RecyclerView
     */
    private void initRecyclerView() {
        initLayoutManager();

        initItemDivider();

        initAdapter();

        initItemClickListener();
    }

    /**
     * 设置布局管理器
     */
    private void initLayoutManager() {
        /**
         * 用于实现列表布局
         */
        LinearLayoutManager manager = new LinearLayoutManager(this);
        manager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(manager);

        /**
         * 用于实现网格布局
         */
//        GridLayoutManager manager = new GridLayoutManager(this, 3);
//        manager.setOrientation(GridLayoutManager.VERTICAL);
//        recyclerView.setLayoutManager(manager);

        /**
         * 用于实现瀑布流
         * 第一个参数表示布局的列数/行数
         * 第二个参数表示布局的方向
         *  StaggeredGridLayoutManager.VERTICAL -- 表示布局纵向排列
         *  StaggeredGridLayoutManager.HORIZONTAL -- 表示布局横向排列
         */
//        StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
//        manager.setOrientation(StaggeredGridLayoutManager.HORIZONTAL);
//        recyclerView.setLayoutManager(manager);
    }

    /**
     * 设置 adapter
     */
    private void initAdapter() {
        adapter = new MyRecyclerViewAdapter(this, initBookList());
        recyclerView.setAdapter(adapter);
    }

    /**
     * 设置 点击或长按事件监听
     */
    private void initItemClickListener() {
        OnRecyclerViewItemClickListener itemClickListener = new OnRecyclerViewItemClickListener() {
            /**
             * item 点击事件
             *
             * @param position
             */
            @Override
            public void onItemClick(int position) {
                Toast.makeText(RecyclerViewActivity.this, position + "被点击", Toast.LENGTH_SHORT).show();
            }

            /**
             * item 长按事件
             * @param position
             */
            @Override
            public boolean onItemLongClick(int position) {
                Toast.makeText(RecyclerViewActivity.this, position + "被长按", Toast.LENGTH_SHORT).show();
                return true;
            }
        };
        adapter.setOnRecyclerViewItemClickListener(itemClickListener);
    }

    /**
     * 给 item 添加分割线
     * 注意:只适用于列表布局(LinearLayout)的 RecyclerView
     *       网格布局(GridLayout)和流式布局(StaggeredGridLayout)的 RecyclerView 就不适用了。
     */
       private void initItemDivider() {
        //添加 Android 自带的分割线
//        DividerItemDecoration divider = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
        //添加 分割线,但最后一个 item 不添加分割线的效果
        CustomDividerItemDecoration divider = new CustomDividerItemDecoration(this, DividerItemDecoration.VERTICAL);
        //添加 自定义图片/ 图形 的分割线
        divider.setDrawable(getResources().getDrawable(R.drawable.line_gradient));
        recyclerView.addItemDecoration(divider);
    }

    /**
     * 初始化 集合 数据
     *
     * @return mBookList
     */
    private List<Book> initBookList() {

        List<Book> list = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            list.add(new Book("book" + i, "author" + i));
        }
        return list;
    }

    public class MyRecyclerViewAdapter extends RecyclerView.Adapter<BookViewHolder> implements View.OnClickListener, View.OnLongClickListener {

        Context context;
        List<Book> list;
        private OnRecyclerViewItemClickListener itemClickListener = null;

        /**
         * 设置 item 点击监听器
         * @param itemClickListener
         */
        public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener itemClickListener) {
            this.itemClickListener = itemClickListener;
        }

        public MyRecyclerViewAdapter(Context context, List<Book> list) {
            this.context = context;
            this.list = list;
        }

        @Override
        public BookViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(context).inflate(R.layout.viewholder_recyclerview, parent, false);
            BookViewHolder viewHolder = new BookViewHolder(view);

            view.setOnClickListener(this);
            view.setOnLongClickListener(this);
            return viewHolder;
        }

        @Override
        public void onBindViewHolder(BookViewHolder holder, int position) {
            holder.textview.setText(list.get(position).toString());

            if (itemClickListener == null) {
                return;
            }

            //被点击的 item 设置 tag 标签,用于 item 被点击时获取 position 索引值
            holder.itemView.setTag(position);
        }

        @Override
        public int getItemCount() {
            return list.size();
        }

        /**
         * 当 item 被点击时,调用 item 点击监听,执行点击回调
         * @param v
         */
        @Override
        public void onClick(View v) {
            if (itemClickListener == null) {
                return;
            }

            //被点击的 item 获取 tag 标签,即 position 索引值
            itemClickListener.onItemClick((Integer) v.getTag());
        }

        @Override
        public boolean onLongClick(View v) {
            return itemClickListener.onItemLongClick((Integer) v.getTag());
        }
    }

    /**
     * RecyclerView 的 ViewHolder 实现类
     */
    public class BookViewHolder extends RecyclerView.ViewHolder {

        TextView textview;

        public BookViewHolder(View itemView) {
            super(itemView);
            textview = itemView.findViewById(R.id.textview);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203

参照 DividerItemDecoration 自定义 item 的分割线

/**
 * 最后一个 item 不添加分割线
 * 只能用于 LinearLayoutManager 列表布局,不能用于网格布局(GridLayoutManager)和瀑布流(StaggeredGridLayoutManager)
 */

public class CustomDividerItemDecoration extends RecyclerView.ItemDecoration {

    public static final int HORIZONTAL = LinearLayout.HORIZONTAL;
    public static final int VERTICAL = LinearLayout.VERTICAL;

    private static final String TAG = "CustomDividerItem";
    private static final int[] ATTRS = new int[]{ android.R.attr.listDivider };

    private Drawable mDivider;

    /**
     * Current orientation. Either {@link #HORIZONTAL} or {@link #VERTICAL}.
     */
    private int mOrientation;

    private final Rect mBounds = new Rect();

    /**
     * 只能用于 LinearLayoutManager 列表布局,不能用于网格布局(GridLayoutManager)和瀑布流(StaggeredGridLayoutManager)
     *
     * @param context Current context, it will be used to access resources.
     * @param orientation Divider orientation. Should be {@link #HORIZONTAL} or {@link #VERTICAL}.
     */
    public CustomDividerItemDecoration(Context context, int orientation) {
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        if (mDivider == null) {
            Log.w(TAG, "@android:attr/listDivider was not set in the theme used for this "
                    + "DividerItemDecoration. Please set that attribute all call setDrawable()");
        }
        a.recycle();
        setOrientation(orientation);
    }

    /**
     * Sets the orientation for this divider. This should be called if
     * {@link RecyclerView.LayoutManager} changes orientation.
     *
     * @param orientation {@link #HORIZONTAL} or {@link #VERTICAL}
     */
    public void setOrientation(int orientation) {
        if (orientation != HORIZONTAL && orientation != VERTICAL) {
            throw new IllegalArgumentException(
                    "Invalid orientation. It should be either HORIZONTAL or VERTICAL");
        }
        mOrientation = orientation;
    }

    /**
     * Sets the {@link Drawable} for this divider.
     *
     * @param drawable Drawable that should be used as a divider.
     */
    public void setDrawable(@NonNull Drawable drawable) {
        if (drawable == null) {
            throw new IllegalArgumentException("Drawable cannot be null.");
        }
        mDivider = drawable;
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (parent.getLayoutManager() == null || mDivider == null) {
            return;
        }
        if (mOrientation == VERTICAL) {
            drawVertical(c, parent);
        } else {
            drawHorizontal(c, parent);
        }
    }

    private void drawVertical(Canvas canvas, RecyclerView parent) {
        canvas.save();
        final int left;
        final int right;
        //noinspection AndroidLintNewApi - NewApi lint fails to handle overrides.
        if (parent.getClipToPadding()) {
            left = parent.getPaddingLeft();
            right = parent.getWidth() - parent.getPaddingRight();
            canvas.clipRect(left, parent.getPaddingTop(), right,
                    parent.getHeight() - parent.getPaddingBottom());
        } else {
            left = 0;
            right = parent.getWidth();
        }

        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount - 1; i++) {
            final View child = parent.getChildAt(i);
            parent.getDecoratedBoundsWithMargins(child, mBounds);
            final int bottom = mBounds.bottom + Math.round(child.getTranslationY());
            final int top = bottom - mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(canvas);
        }
        canvas.restore();
    }

    private void drawHorizontal(Canvas canvas, RecyclerView parent) {
        canvas.save();
        final int top;
        final int bottom;
        //noinspection AndroidLintNewApi - NewApi lint fails to handle overrides.
        if (parent.getClipToPadding()) {
            top = parent.getPaddingTop();
            bottom = parent.getHeight() - parent.getPaddingBottom();
            canvas.clipRect(parent.getPaddingLeft(), top,
                    parent.getWidth() - parent.getPaddingRight(), bottom);
        } else {
            top = 0;
            bottom = parent.getHeight();
        }

        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount - 1; i++) {
            final View child = parent.getChildAt(i);
            parent.getLayoutManager().getDecoratedBoundsWithMargins(child, mBounds);
            final int right = mBounds.right + Math.round(child.getTranslationX());
            final int left = right - mDivider.getIntrinsicWidth();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(canvas);
        }
        canvas.restore();
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
                               RecyclerView.State state) {
        if (mDivider == null) {
            outRect.set(0, 0, 0, 0);
            return;
        }
        if (mOrientation == VERTICAL) {
            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
        } else {
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145

item 点击事件监听

OnRecyclerViewItemClickListener.java

public interface OnRecyclerViewItemClickListener {
    /**
     * 点击事件
     * @param position
     */
    void onItemClick(int position);

    /**
     * 长按事件
     * @param position
     */
    void onItemLongClick(int position);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

实体 Bean

Book.java

public class Book {

    private String name;
    private String author;

    public Book(String name, String author){
        this.name = name;
        this.author = author;
    }

    @Override
    public String toString() {
        return "name: " + name + "\n" + "author: " + author;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

布局文件

activity_recyclerview.xml

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

    <TextView
        android:layout_width="wrap_content"
        android:text="recyclervie"
        android:layout_marginBottom="15dp"
        android:layout_height="wrap_content" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

viewholder_recyclerview.xml

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

    <TextView
        android:id="@+id/textview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:drawableRight="@drawable/mechanic"
        android:padding="15dp"
        android:text="item" />

</LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

line_gradient.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <gradient
        android:startColor="#FFFFFFFF"
        android:centerColor="#FF0000FF"
        android:endColor="#FFFFFFFF"
        android:type="linear"/>

    <!--尝试这个颜色搭配的效果-->
    <!--<gradient-->
        <!--android:startColor="#FFFF0000"-->
        <!--android:centerColor="#FF00FF00"-->
        <!--android:endColor="#FF0000FF"-->
        <!--android:type="linear" />-->

    <!--DividerItemDecoration.HORIZONTAL 时设置-->
    <!--<size android:width="3dp" />-->

    <!--DividerItemDecoration.VERTICAL 时设置-->
    <size android:height="3dp" />

</shape>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

RecyclerView 的 item 的点击事件

RecyclerView 竟然找不到 setOnItemClickListener() 方法,网上的写法都是自定义接口来实现
本例中,已经添加了 item 的点击事件和长按事件监听

/**
 * item 点击事件监听
 */
public interface OnItemClickListener{
    /**
     * 点击事件
     * @param position
     */
    void onItemClick(int position);

    /**
     * 长按事件
     * @param position
     */
    void onItemLongClick(int position);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

这里还是有几点需要注意的地方

1.RecyclerView 需要用到 布局管理器,如未添加,则 item 没有显示出来

这里写图片描述

/**
 * 用于实现列表布局
 */
LinearLayoutManager manager = new LinearLayoutManager(this);
manager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(manager);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
如果需要改成横向的列表,只需改变一行代码即可
  • 1
manager.setOrientation(LinearLayoutManager.HORIZONTAL);
  • 1
RecyclerView 除了 LinearLayoutManager(列表布局)之外
还提供了 GridlayoutManager(网格布局) 和 StaggeredGridlayoutManager(瀑布流)
  • 1
  • 2
/**
 * 用于实现网格布局
 */
GridLayoutManager manager = new GridLayoutManager(this, 3);
manager.setOrientation(GridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(manager);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
如果需要改成横向的网格,只需改变一行代码即可
  • 1
manager.setOrientation(GridLayoutManager.HORIZONTAL);
  • 1
/**
 * 用于实现瀑布流
 * 第一个参数表示布局的列数/行数
 * 第二个参数表示布局的方向
 *  StaggeredGridLayoutManager.VERTICAL -- 表示布局纵向排列
 *  StaggeredGridLayoutManager.HORIZONTAL -- 表示布局横向排列
 */
StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(manager);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
如果需要改成横向的瀑布流,只需添加/改变一行代码即可
  • 1
manager.setOrientation(StaggeredGridLayoutManager.HORIZONTAL);
  • 1

2.RecyclerView 有自己的 Adapter (即,RecyclerView.Adapter)

这里写图片描述

这里的 Adapter 带了泛型,泛型我们可以写 RecyclerView.ViewHolder,因为 BookViewHolder 就是其子类,但之所以这里没有写 RecyclerView.ViewHolder,是因为这里有个小问题需要注意。

根据快捷键自动实现父类方法,代码如下

这里写图片描述

存在两个问题

1.创建 RecyclerView.ViewHolder 对象时报错,提示 RecyclerView 里的 ViewHolder 类是抽象类(abstract)
  • 1

这里写图片描述

2.在 onBindViewHolder 回调中,找不到我们自己写的 item 布局里的控件
  • 1

这里写图片描述

所以,建议在泛型里写我们自己定义的 BookViewHolder 而不是直接写 RecyclerView.ViewHolder,这样在实现父类方法时,直接生成了对应的泛型,而不需要我们在一个一个的去修改(如果忘记修改了,就会需要我们一个一个小问题的去排除),当然只是建议。

这里写图片描述

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<BookViewHolder> {

        Context context;
        List<Book> list;

        public MyRecyclerViewAdapter(Context context, List<Book> list){
            this.context = context;
            this.list = list;
        }

        @Override
        public BookViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(context).inflate(R.layout.viewholder_recyclerview, parent, false);
            BookViewHolder viewHolder = new BookViewHolder(view);
            return viewHolder;
        }

        @Override
        public void onBindViewHolder(BookViewHolder holder, int position) {
            holder.textview.setText(list.get(position).toString());
        }

        @Override
        public int getItemCount() {
            return list.size();
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

3.在 Adapter 的 onCreateViewHolder 方法中,进行加载 item 布局时,建议用下面两种方式

@Override
        public BookViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(context).inflate(R.layout.viewholder_recyclerview, parent, false);
            BookViewHolder viewHolder = new BookViewHolder(view);
            return viewHolder;
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

@Override
        public BookViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = View.inflate(context, R.layout.viewholder_recyclerview, null);
            BookViewHolder viewHolder = new BookViewHolder(view);
            return viewHolder;
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

先看一下报错的情况

这里写图片描述

这里写图片描述

上面两种情况,会出现 IllegalStateException,并且没有提示错误位置
  • 1

这里写图片描述

我们看一下 inflate 的源码

这里写图片描述

这里写图片描述

我们可以看到,如果不传 boolean attachToRoot 参数则默认传的是 root != null
而上述两种情况中,ViewGroup 对象并不是 null
  • 1
  • 2
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/174664
推荐阅读
相关标签
  

闽ICP备14008679号