Android RecyclerView 之 列表宫格布局的切换

前言

RecyclerView 的使用我就不再多说,接下来的几篇文章主要说一下 RecyclerView 的实用小功能,包括 列表宫格的切换,吸顶效果,多布局效果等,今天这篇文章就来实现一下列表宫格的切换,效果如下


一、数据来源

数据来源于知乎日报API,采用 okhttp+retrofit 组合方式请求获取,网络请求没有进行二次封装,只是简单请求数据源,对于有需求的用户自行进行封装修改。

二、使用步骤

1.引入库

  //万能适配器implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50'//卡片布局implementation 'androidx.cardview:cardview:1.0.0'//图片加载implementation 'com.github.bumptech.glide:glide:4.9.0'//json解析implementation 'com.alibaba:fastjson:1.2.61'//标题栏implementation 'com.github.goweii:ActionBarEx:3.2.2'// 只引入ActionBarEximplementation 'com.github.goweii.ActionBarEx:actionbarex:3.2.2'// 引入ActionBarCommon/Search/Super,依赖于ActionBarEximplementation 'com.github.goweii.ActionBarEx:actionbarex-common:3.2.2'

2.获取数据

 使用如下 URL 进行数据请求:API 使用的 HTTP Method 均为 GET

https://news-at.zhihu.com/api/3/news/hot

响应实例:

{"recent": [{"news_id": 3748552,"thumbnail": "http://p3.zhimg.com/67/6a/676a8337efec71a100eea6130482091b.jpg","title": "长得漂亮能力出众性格单纯的姑娘为什么会没有男朋友?","url": "http://daily.zhihu.com/api/2/news/3748552"}]
}

根据实例生成实体类 NewsListBean 实现序列换接口 Serializable

public class NewsListBean implements Serializable {private String date;private List<Recent> recent;public String getDate() {return date;}public void setDate(String date) {this.date = date;}public List<Recent> getRecent() {return recent;}public void setRecent(List<Recent> recent) {this.recent = recent;}public static class Recent implements Serializable {private String news_id;private String thumbnail;private String title;private String url;public String getNews_id() {return news_id;}public void setNews_id(String news_id) {this.news_id = news_id;}public String getThumbnail() {return thumbnail;}public void setThumbnail(String thumbnail) {this.thumbnail = thumbnail;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}}
}

写一个 接口类用来管理 API ,可以单独放在一个文件夹下

public interface ApiUrl {@GET("/api/4/news/hot")Call<NewsListBean> getPic();}

3.主要代码

1 activity_main.xml

这里使用了三方库  ActionBarEx 实现了沉浸式标题栏,使用了系统的 ProgressBar 实现请求加载框

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><per.goweii.actionbarex.ActionBarExandroid:id="@+id/abc_main_return"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#14a4fb"app:ab_autoImmersion="false"app:ab_bottomLineColor="#f3f3f3"app:ab_bottomLineHeight="0dp"app:ab_statusBarColor="#00000000"app:ab_statusBarMode="dark"app:ab_statusBarVisible="true"app:ab_titleBarHeight="50dp"app:ab_titleBarLayout="@layout/top" /><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/zh_lv"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_below="@+id/abc_main_return" /><ProgressBarandroid:id="@+id/progressbar"style="@style/Base.Widget.AppCompat.ProgressBar"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:visibility="gone" />
</RelativeLayout>

2 zh_item_layout.xml

列表子布局 ,采用 CardView 卡片布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/zh_card_View"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="@dimen/dp_10"android:layout_marginTop="10dp"android:layout_marginRight="@dimen/dp_10"android:layout_marginBottom="@dimen/dp_10"app:cardBackgroundColor="#ffffff"app:cardCornerRadius="10dp"app:cardElevation="10dp"app:cardPreventCornerOverlap="true"app:cardUseCompatPadding="false"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="120dp"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/transparent"><ImageViewandroid:id="@+id/news_image"android:layout_width="70dp"android:layout_height="70dp"android:layout_centerVertical="true"android:layout_margin="10dp"android:elevation="2dp"android:scaleType="fitXY" /><TextViewandroid:id="@+id/news_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:layout_marginStart="10dp"android:layout_marginTop="10dp"android:layout_marginEnd="10dp"android:layout_toEndOf="@id/news_image"android:ellipsize="end"android:maxEms="15"android:singleLine="true"android:textColor="@color/black"android:textSize="20sp" /></RelativeLayout></RelativeLayout></androidx.cardview.widget.CardView>

3 zh_grid__item_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/zh_card_View"android:layout_width="match_parent"android:layout_height="180dp"android:layout_marginLeft="@dimen/dp_10"android:layout_marginTop="10dp"android:layout_marginRight="@dimen/dp_10"android:layout_marginBottom="@dimen/dp_10"app:cardBackgroundColor="#ffffff"app:cardCornerRadius="10dp"app:cardElevation="10dp"app:cardPreventCornerOverlap="true"app:cardUseCompatPadding="false"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/transparent"android:gravity="center"android:orientation="vertical"android:padding="@dimen/dp_10"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="3"><ImageViewandroid:id="@+id/news_image"android:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="fitXY" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:gravity="center"><TextViewandroid:id="@+id/news_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:ellipsize="end"android:maxEms="8"android:singleLine="true"android:textColor="@color/black"android:textSize="20sp" /></LinearLayout></LinearLayout></androidx.cardview.widget.CardView>

4 NewsListAdapter 适配器

public class NewsListAdapter extends BaseQuickAdapter<NewsListBean.Recent, BaseViewHolder> {public NewsListAdapter(int layoutResId, @Nullable List<NewsListBean.Recent> data) {super(layoutResId, data);}@Overrideprotected void convert(@NonNull BaseViewHolder helper, NewsListBean.Recent item) {helper.setText(R.id.news_title, item.getTitle());String img = item.getThumbnail();ImageView newsImage = helper.getView(R.id.news_image);Glide.with(mContext).asBitmap().load(img).diskCacheStrategy(DiskCacheStrategy.ALL).into(newsImage);helper.addOnClickListener(R.id.zh_card_View);}}

5 BaseActivity 基类

public abstract class BaseActivity extends AppCompatActivity {@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {Window window = getWindow();// 5.0以上系统状态栏透明if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN| View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);window.setStatusBarColor(Color.TRANSPARENT);}if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {// 全屏显示,隐藏状态栏和导航栏,拉出状态栏和导航栏显示一会儿后消失。window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE// | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION// | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION// | View.SYSTEM_UI_FLAG_FULLSCREEN| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);} else {// 全屏显示,隐藏状态栏window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);}}//预防软键盘挡住输入框getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);//禁止横屏setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);super.onCreate(savedInstanceState);}}

6 MainActivity 主要代码 

这里主要通过一个 boolean 值 isGrid 来判断是否切换状态来加载不同的布局,以及布局管理器来达到实际效果

public class MainActivity extends BaseActivity {private RecyclerView zhLv;private ProgressBar proBar;private NewsListAdapter adapter;private List<NewsListBean.Recent> mList = new ArrayList<>();private static final int REQUEST_EXTERNAL_STORAGE = 1;private static String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};private ImageView menuBtn;private LinearLayoutManager layoutManager;private ImageView btnImg;private LinearLayout backLayoput;public static void verifyStoragePermissions(Activity activity) {int permission = ActivityCompat.checkSelfPermission(activity,Manifest.permission.WRITE_EXTERNAL_STORAGE);if (permission != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE,REQUEST_EXTERNAL_STORAGE);}}private boolean isGrid = false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);verifyStoragePermissions(MainActivity.this);initView();initData();menuBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {switchLayout();}});}private void switchLayout() {if (isGrid) {layoutManager = new LinearLayoutManager(this);adapter = new NewsListAdapter(R.layout.zh_item_layout, mList);zhLv.setAdapter(adapter);} else {layoutManager = new GridLayoutManager(this, 2);adapter = new NewsListAdapter(R.layout.zh_grid__item_layout, mList);zhLv.setAdapter(adapter);}zhLv.setLayoutManager(layoutManager);isGrid = !isGrid;}private void initView() {zhLv = findViewById(R.id.zh_lv);proBar = findViewById(R.id.progressbar);menuBtn = findViewById(R.id.btn_main_menu);btnImg = findViewById(R.id.btn_main_menu);backLayoput = findViewById(R.id.btn_back_layout);backLayoput.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {finish();}});layoutManager = new LinearLayoutManager(MainActivity.this);zhLv.setLayoutManager(layoutManager);adapter = new NewsListAdapter(R.layout.zh_item_layout, mList);zhLv.setAdapter(adapter);}private void initData() {proBar.setVisibility(View.VISIBLE);Retrofit retrofit = new Retrofit.Builder().baseUrl("https://news-at.zhihu.com/")//设置数据解析器.addConverterFactory(GsonConverterFactory.create()).build();ApiUrl apiUrl = retrofit.create(ApiUrl.class);Call<NewsListBean> call = apiUrl.getPic();call.enqueue(new Callback<NewsListBean>() {@Overridepublic void onResponse(Call<NewsListBean> call, Response<NewsListBean> response) {List<NewsListBean.Recent> recent = response.body().getRecent();if (response.body() != null && recent.size() > 0) {try {mList.addAll(recent);adapter.setNewData(mList);proBar.setVisibility(View.GONE);} catch (Exception e) {String message = e.getMessage();e.printStackTrace();}}}@Overridepublic void onFailure(Call<NewsListBean> call, Throwable t) {Log.e("mmm", "errow " + t.getMessage());}});}}

总结

一个小小的很实用的功能就完成了,下一篇文章会接着实现RecyclerView 吸顶效果,后续还会加上列表本地缓存等功能,Demo 在此系列文章完结附上,不妨点赞收藏哦~

青山不改,绿水长流 有缘江湖再见 ~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/112729.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++八股记录

C内存管理 C中&#xff0c;内存分成5个区。 栈&#xff1a;函数内局部变量&#xff1b;自动管理&#xff0c;效率高&#xff0c;但空间较小&#xff1b; 堆&#xff1a;new分配的内存块&#xff1b;手动管理&#xff0c;效率低&#xff0c;但空间大&#xff1b; 自由存储区&…

【数据结构与算法 模版】高频题刷题模版

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【】&#xff0c;使用【】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&#xff1a;目标公…

实现带头双向循环链表

&#x1f308;带头双向循环链表 描述&#xff1a;一个节点内包含两个指针&#xff0c;一个指向上一个节点&#xff0c;另一个指向下一个节点。哨兵位指向的下一个节点为头节点&#xff0c;哨兵位的上一个指向尾节点。 结构优势&#xff1a;高效率找尾节点&#xff1b;高效率插入…

设计模式——装饰器模式

装饰器模式 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其结构。这种类型的设计模式属于结构型模式&#xff0c;它是作为现有的类的一个包装。 装饰器模式通过将对象包装在装饰器类中&#xff0c;以便动态…

04架构管理之分支管理实践-一种git分支管理最佳实践

专栏说明&#xff1a;针对于企业的架构管理岗位&#xff0c;分享架构管理岗位的职责&#xff0c;工作内容&#xff0c;指导架构师如何完成架构管理工作&#xff0c;完成架构师到架构管理者的转变。计划以10篇博客阐述清楚架构管理工作&#xff0c;专栏名称&#xff1a;架构管理…

【数据结构】二叉数的存储与基本操作的实现

文章目录 &#x1f340;二叉树的存储&#x1f333;二叉树的基本操作&#x1f431;‍&#x1f464;二叉树的创建&#x1f431;‍&#x1f453;二叉树的遍历&#x1f3a1;前中后序遍历&#x1f4cc;前序遍历&#x1f4cc;中序遍历&#x1f4cc;后续遍历 &#x1f6eb;层序遍历&am…

Vue2向Vue3过度核心技术插槽

目录 1 插槽-默认插槽1.作用2.需求3.问题4.插槽的基本语法5.代码示例6.总结 2 插槽-后备内容&#xff08;默认值&#xff09;1.问题2.插槽的后备内容3.语法4.效果5.代码示例 3 插槽-具名插槽1.需求2.具名插槽语法3.v-slot的简写4.总结 4 作用域插槽1.插槽分类2.作用3.场景4.使用…

C#,《小白学程序》第六课:队列(Queue)的应用,《实时叫号系统》

医院里面常见的叫号系统怎么实现的&#xff1f; 1 文本格式 /// <summary> /// 下面定义一个新的队列&#xff0c;用于演示《实时叫号系统》 /// </summary> Queue<Classmate> q2 new Queue<Classmate>(); /// <summary> /// 《小白学程序》第…

ChromeOS 的 Linux 操作系统和 Chrome 浏览器分离

导读科技媒体 Ars Technica 报道称&#xff0c;谷歌正在将 ChromeOS 的浏览器从操作系统中分离出来 —— 让它变得更像 Linux。虽然目前还没有任何官方消息&#xff0c;但这项变化可能会在本月的版本更新中推出。 据介绍&#xff0c;谷歌将该项目命名为 "Lacros"——…

监控抽烟检测识别算法

监控抽烟检测识别算法采用yolov7系列网络模型深度学习图像识别技术&#xff0c;监控抽烟检测识别算法能够准确识别人员抽烟的动作和烟雾&#xff0c;监控抽烟检测识别算法一旦发现有人员在禁烟区域内抽烟&#xff0c;将立即触发预警。YOLO的结构非常简单&#xff0c;就是单纯的…

遇到 Binder这些面试题,你会怎么答?

作为开发人员&#xff0c;每个人都有每个人擅长领域&#xff0c;自然也有自己不擅长的领域&#xff0c;很难成为完美的一个全栈开发。在面试中最怕遇见的一件事是面试官专挑你不擅长的领域进行提问&#xff0c;目的就是看你遇到问题的应变能力。 接下给大家分享一个面试中容易被…

Linux系统编程:线程控制

目录 一. 线程的创建 1.1 pthread_create函数 1.2 线程id的本质 二. 多线程中的异常和程序替换 2.1 多线程程序异常 2.2 多线程中的程序替换 三. 线程等待 四. 线程的终止和分离 4.1 线程函数return 4.2 线程取消 pthread_cancel 4.3 线程退出 pthread_exit 4.4 线程…

QML Book 学习基础3(动画)

目录 主要动画元素 例子&#xff1a; 非线性动画 分组动画 Qt 动画是一种在 Qt 框架下创建交互式和引人入胜的图形用户界面的方法&#xff0c;我们可以认为是对某个基础元素的多个设置 主要动画元素 PropertyAnimation-属性值变化时的动画 NumberA…

【操作系统】聊聊局部性原理是如何提升性能的

对于目前数据主导的系统&#xff0c;大多数都是Java/Go 技术栈MySQL&#xff0c;但是随着时间的推移&#xff0c;数据库数据的数据量过多&#xff0c;并且会频繁访问热点数据&#xff0c;为了提升系统的性能&#xff0c;一般都是加入缓存中间件、Redis。 局部性原理 我们知道…

springboot小知识:配置feign服务超时时间

背景&#xff1a;当前项目通过feign服务调用了其他两个项目的接口&#xff0c;但是由于特殊需求&#xff0c;需要调整某一个项目的feign服务的默认超时时间&#xff1a; 默认连接超时10秒&#xff0c;默认读取超时时间 60秒 1.找到定义的FeignClient 2.根据FeignClient定义的名…

创建python环境——Anaconda

在Windows中安装Anaconda和简单使用 一.Anaconda发行概述 Anaconda是一个可以便捷获取和管理包&#xff0c;同时对环境进行统一管理的发行版本&#xff0c;它包含了conda、 Python在内的超过180个科学包及其依赖项。 1.Anaconda发行版本具有以下特点&#xff1a; (1)包含了…

Redis笔记——(狂神说)

Nosql概述 为什么要用NoSql&#xff1f; 1、单机mysql的年代&#xff1a;90年代&#xff0c;网站访问量小&#xff0c;很多使用静态网页html写的&#xff0c;服务器没压力。 当时瓶颈是&#xff1a;1)数据量太大一个机器放不下。2)数据的索引(BTree)&#xff0c;一个机器内存也…

京东商品详情数据(H5端,PC端)高效对接第三方API接口

利用电商API获取数据的步骤 1.申请API接口注册Key和secret接入&#xff1a;首先要在相应电商平台上注册账号并申请API接口。 2.获取授权&#xff1a;在账号注册成功后&#xff0c;需要获取相应的授权才能访问电商API。 3.调用API&#xff1a;根据电商API提供的请求格式&…

【Spring】什么是 AOP(面向切面编程) ? 为什么要有 AOP ? 如何实现 Spring AOP ?

文章目录 前言一、什么是 AOP ?二、为什么要使用 AOP ?三、 AOP 的组成四、Spring AOP 的实现1, 添加依赖2, 定义切面3, 定义切点4, 定义通知5, 创建连接点 总结 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你: &#x1f4d5; JavaSE基础: 基础语法…

Excel:如何实现分组内的升序和降序?

一、POWER 1、构建辅助列D列&#xff0c;在D2单元格输入公式&#xff1a; -POWER(10,COUNTA($A$2:A2)3)C2 2、选中B1:D10&#xff0c;注意不能宣导A列的合并单元格&#xff0c;进行以下操作&#xff1a; 3、删除辅助列即可 二、COUNTA 第一步&#xff0c;D2建立辅助列&#xf…