Android APP 基于RecyclerView框架工程(知识体系积累)

说明这个简单的基于RecyclerView的框架作用在于自己可以将平时积累的一些有效demo整合起来(比如音视频编解码的、opengles的以及其他也去方向的、随着项目增多,工程量的增加,后期想高效的分析和查找并不容易),不用搞太多的工程,不像多个工程过于分散也占空间。


1 基于RecyclerView框架工程实现原理说明

该工程通过config.xml配置文件获取每一个网格中的基本信息,并将其存储到itemlist中。应用启动后,点击网格中的按键,每个按键可以按需启动一个应用。适用于长期积累自己的知识体系。

接下来直接上干货,粘过去可以直接用的那种~。平台是基于Android12的。

框架工程代码完整解读(android Q)

2.1 layout布局文件解读

res/layout 主界面 activity_main.xml内容如下:

<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"tools:ignore="ExtraText"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recyclerview"android:layout_width="match_parent"android:layout_height="500dp"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /><TextViewandroid:id="@+id/textviewMainMenu"android:layout_width="match_parent"android:layout_height="200dp"android:text="@string/title"android:background="@color/white"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toBottomOf="@+id/recyclerview" />
</androidx.constraintlayout.widget.ConstraintLayout>

RecycleView中需要使用的配置文件item参考实现如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"><TextViewandroid:id="@+id/textView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="4dp"android:layout_marginTop="18dp"android:text="@string/title"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/button"android:layout_height="wrap_content"android:layout_width="wrap_content"android:text="@string/h264_decode_demo"app:layout_constraintStart_toStartOf="@+id/textView"app:layout_constraintTop_toBottomOf="@+id/textView"tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>

2.2 配置文件体系构建

使用res/xml 配置文件 config.xml内容如下:

<?xml version="1.0" encoding="utf-8"?>
<items><item><description>H264解码一个download目录下的out.h264码流</description><buttonName>H264解码</buttonName><activityName>com.wds.videoexample.Activity1</activityName></item><item><description>通过mediaprojection获取投屏数据,使用H264编码一个sdcard/路径下的codec.h264码流</description><buttonName>H264编码</buttonName><activityName>com.example.app.Activity2</activityName></item><item><description>通过camerax获取投屏数据,使用H264编码一个sdcard/路径下的codec.h264码流</description><buttonName>Button03</buttonName><activityName>com.example.app.Activity3</activityName></item>。。。
<items>

关于元素的个数和tag,大家可以自己按照自己的需求自定义。接下来有了配置文件,还要有配套的解析器,这里命名为ParseConfig,代码实现如下:

public class ParserConfig {private final static String TAG = "ParserConfig";private static List<Item> itemList;public static List<Item> getItemList() {return itemList;}private static String fullDescription = "";@SuppressLint("DefaultLocale")public static void initItemList(Context context) {itemList = new ArrayList<>();XmlResourceParser parser = context.getResources().getXml(R.xml.config);Log.d(TAG,"initItemLis");String description = null;String buttonName = null;String activityName = null;String tagName = null;//String fullDescription = "";int index= 0;try {int eventType = parser.getEventType();while (eventType != XmlPullParser.END_DOCUMENT) {if (eventType == XmlPullParser.START_TAG) {tagName = parser.getName();if ("item".equals(tagName)) {index++;while (parser.next() != XmlPullParser.END_TAG) {if (parser.getEventType() == XmlPullParser.TEXT) {description = parser.getText();fullDescription += "\ndemo"+String.format("%03d",index)+":"+description+"\n";}}while (parser.next() != XmlPullParser.END_TAG) {if (parser.getEventType() == XmlPullParser.TEXT) {buttonName = parser.getText();}}while (parser.next() != XmlPullParser.END_TAG) {if (parser.getEventType() == XmlPullParser.TEXT) {activityName = parser.getText();}}if (buttonName != null && activityName != null) {itemList.add(new Item(description,buttonName, activityName));}}}eventType = parser.next();}} catch (XmlPullParserException | IOException e) {e.printStackTrace();}}public static String getFullDescription(){return fullDescription;}
}

这里涉及的itemlist中的元素item定义如下:

public class Item {public String buttonName; //点击按键内容private String activityName;private String description;public Item(String description, String buttonName, String activityName) {this.buttonName = buttonName;this.activityName = activityName;this.description = description;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getButtonName() {return buttonName;}public void setButtonName(String buttonName) {this.buttonName = buttonName;}public String getActivityName() {return activityName;}public void setActivityName(String activityName) {this.activityName = activityName;}
}

2.3 权限的处理

关于权限,使用了一个Permission 专门的类来做运行时权限的处理,代码实现如下:

public class Permission {public static final int REQUEST_MANAGE_EXTERNAL_STORAGE = 1;//需要申请权限的数组private static final String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA};//保存真正需要去申请的权限private static final List<String> permissionList = new ArrayList<>();public static int RequestCode = 100;public static void requestManageExternalStoragePermission(Context context, Activity activity) {if (!Environment.isExternalStorageManager()) {showManageExternalStorageDialog(activity);}}private static void showManageExternalStorageDialog(Activity activity) {AlertDialog dialog = new AlertDialog.Builder(activity).setTitle("权限请求").setMessage("请开启文件访问权限,否则应用将无法正常使用。").setNegativeButton("取消", null).setPositiveButton("确定", (dialogInterface, i) -> {Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);activity.startActivityForResult(intent, REQUEST_MANAGE_EXTERNAL_STORAGE);}).create();dialog.show();}public static void checkPermissions(Activity activity) {for (String permission : permissions) {if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {permissionList.add(permission);}}if (!permissionList.isEmpty()) {requestPermission(activity);}}public static void requestPermission(Activity activity) {ActivityCompat.requestPermissions(activity,permissionList.toArray(new String[0]),RequestCode);}
}

这样,如果后面又更多的权限,都可以使用该方法来处理,处理方式为:

Permission.checkPermissions(this);
Permission.requestManageExternalStoragePermission(getApplicationContext(), this);

2.4 基于RecyclerView的框架工程 | 主流程代码参考实现

这里给出框架工程的代码的实现。具体如下:

public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";private RecyclerView mRecyclerView;MyAdapter mMyAdapter ;private List<Item> itemList;private TextView mTextViewMainmenu;@SuppressLint("DefaultLocale")@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});mTextViewMainmenu = findViewById(R.id.textviewMainMenu);mTextViewMainmenu.setMovementMethod(ScrollingMovementMethod.getInstance());mRecyclerView = findViewById(R.id.recyclerview);ParserConfig.initItemList(this);mTextViewMainmenu.setText(ParserConfig.getFullDescription());itemList = ParserConfig.getItemList();mMyAdapter = new MyAdapter();mRecyclerView.setAdapter(mMyAdapter);GridLayoutManager layoutManager = new GridLayoutManager(MainActivity.this,3);mRecyclerView.setLayoutManager(layoutManager);DividerItemDecoration mDivider = newDividerItemDecoration(this, DividerItemDecoration.VERTICAL);mRecyclerView.addItemDecoration(mDivider);DividerItemDecoration mDivider2 = newDividerItemDecoration(this, DividerItemDecoration.HORIZONTAL);mRecyclerView.addItemDecoration(mDivider2);}class MyAdapter extends RecyclerView.Adapter<MyViewHoder> {@NonNull@Overridepublic MyViewHoder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = View.inflate(MainActivity.this, R.layout.item_list, null);return new MyViewHoder(view);}@Overridepublic void onBindViewHolder(@NonNull MyViewHoder holder, int position) {Item item = itemList.get(position);@SuppressLint("DefaultLocale") String title_text = getString(R.string.wbs_demo) + String.format("%03d", position+1);holder.mTitleTv.setText(title_text);holder.mButton.setText(item.buttonName);holder.mButton.setTag(position);holder.mButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {int position = (int)view.getTag();mTextViewMainmenu.setText(itemList.get(position).getDescription());Handler handler = new Handler();handler.postDelayed(new Runnable() {@Overridepublic void run() {if (position == 0) {Intent intent = new Intent(MainActivity.this, H264decoderActivity.class);startActivity(intent);} else if (position == 1) {Intent intent = new Intent(MainActivity.this, H264encoderMediaProjActivity.class);startActivity(intent);} else if (position == 2) {Intent intent = new Intent(MainActivity.this, H264encoderCameraXActivity.class);startActivity(intent);}}}, 3000); //Log.d(TAG,"onclick"+view.getTag());}});}@Overridepublic int getItemCount() {return itemList.size();}}static class MyViewHoder extends RecyclerView.ViewHolder {TextView mTitleTv;Button mButton;public MyViewHoder(@NonNull View itemView) {super(itemView);mTitleTv = itemView.findViewById(R.id.textView);mButton = itemView.findViewById(R.id.button);}}
}

2.5 主框架 demo实现效果

实际运行效果展示如下:

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

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

相关文章

1.Fabric框架

要了解Fabric&#xff0c;首先要知道Hyperledger开源项目。 2015年12月&#xff0c;由开源世界的旗舰组织Linux基金会牵头&#xff0c;30家初始企业成员共同宣布Hyperledger联合项目成立。Hyperledger 超级账本&#xff0c;是首个面向企业应用场景的分布式账本平台&#xff0c…

【每日一练】python编写一个简易计算器

程序代码: #循环语句&#xff0c;条件为真所以循环执行 while True: #定义两个数的变量和运算符号 num1 float(input("第一个数:")) num2 float(input("第一个数:")) syminput("选择运算符 - * /&#xff1a;") #判断运算符号 …

Camera Raw:评级和标签

在 Camera Raw 中&#xff0c;评级 Rating和标签 Label功能为摄影师和图像编辑者提供了一种高效的图像组织和管理方法。通过这些功能&#xff0c;用户可以轻松地对照片进行分类、标记和筛选&#xff0c;以便在大量图像中快速找到需要的照片。 ◆ ◆ ◆ 设置星级 Set Rating 星…

Inconsistent Query Results Based on Output Fields Selection in Milvus Dashboard

题意&#xff1a;在Milvus仪表盘中基于输出字段选择的不一致查询结果 问题背景&#xff1a; Im experiencing an issue with the Milvus dashboard where the search results change based on the selected output fields. Im working on a RAG project using text data conv…

【Java面向对象】二进制I/O

文章目录 1.二进制文件2.二进制 I/O 类2.1 FileInputStream 和 FileOutputStream2.2 FilterInputStream和 FilterOutputStream2.3 DatalnputStream 和 DataOutputStream2.4 BufferedInputStream 和 BufferedOutputStream2.5 ObjectInputStream 和 ObjectOutputStream 2.6 Seria…

防御保护课-防火墙接口配置实验

一、实验拓扑 &#xff08;我做实验用的图如下&#xff09; 二、实验要求 1.防火墙向下使用子接口分别对应生产区和办公区 2.所有分区设备可以ping通网关 三、实验思路 配IP&#xff1b; 划分vlan并配置vlan&#xff1b; 配置路由和安全策略。 四、实验配置 1、画图并…

开源模型应用落地-FastAPI-助力模型交互-进阶篇-RequestDataclasses(三)

一、前言 FastAPI 的高级用法可以为开发人员带来许多好处。它能帮助实现更复杂的路由逻辑和参数处理&#xff0c;使应用程序能够处理各种不同的请求场景&#xff0c;提高应用程序的灵活性和可扩展性。 在数据验证和转换方面&#xff0c;高级用法提供了更精细和准确的控制&#…

【Linux】进程间通信之-- 共享内存与信号量的介绍(下)

前言 上一篇&#xff0c;我们由进程间通信&#xff0c;引入并讲述了管道、匿名管道和命名管道&#xff0c;本节&#xff0c;将继续学习进程间通信的另一种方式之&#xff0c;共享内存。还要学习几个系统调用接口&#xff0c;并演示两个进程通过共享内存来进行通信。。。 目录 1…

工业控制:CANOpen(控制器局域网络)协议快速学习

文章目录 背景协议介绍CAN总线协议CANOpen协议介绍CANOpen诞生背景CANOpen的对象字典 CANOpen的服务数据对象&#xff08;SDO&#xff09; 参考附录问题CAN总线竞争原理在CAN协议中&#xff0c;帧中的ID是发送者的ID还是接收者的ID&#xff1f; 背景 目前很多CANOpen介绍的文章…

循环机制(event loop)之宏任务和微任务

一、前言 js任务分为同步任务和异步任务&#xff0c;异步任务又分为宏任务和微任务&#xff0c;其中异步任务属于耗时的任务。 二、宏任务和微任务有哪些&#xff1f; 宏任务&#xff1a;整体代码script、setTimeout、setInterval、setImmediate&#xff08;Node.js&#xff…

【ARM】SMMU系统虚拟化整理

目录 1.MMU的基本介绍 1.1 特点梳理 2.功能 DVM interface PTW interface 2.1 操作流程 2.1.1 StreamID 2.1.2 安全状态&#xff1a; 2.1.3 HUM 2.1.4 可配置的操作特性 Outstanding transactions per TBU QoS 仲裁 2.2 Cache结构 2.2.1 Micro TLB 2.2.2 Macro…

第四周:机器学习笔记

第四周学习周报 摘要Abstract机器学习任务攻略1.loss on training data1.1 training data的loss过大怎么办&#xff1f;1.2 training data的loss小&#xff0c;但是testing data loss大怎么办&#xff1f; 2. 如何选择一个中最好的模型&#xff1f;2.1 Cross Validation&#x…

知名在线市场 Etsy 允许在其平台上销售 AI 艺术品,但有条件限制|TodayAI

近日&#xff0c;以手工和复古商品著称的在线市场 Etsy 宣布&#xff0c;将允许在其平台上销售 AI 生成的艺术品。这一举措引发了广泛关注和争议。尽管 Etsy 正在接受 AI 艺术的潮流&#xff0c;但平台对这一类商品的销售设置了一些限制。 根据 Etsy 新发布的政策&#xff0c;…

mysql存储引擎和备份

索引 事务 存储引擎 概念&#xff1a;存储引擎&#xff0c;就是一种数据库存储数据的机制&#xff0c;索引的技巧&#xff0c;锁定水平。 存储引擎。存储的方式和存储的格式。 存储引擎也属于mysql当中的组件&#xff0c;实际上操作的&#xff0c;执行的就是数据的读写I/O。…

华为OD机试2024年C卷D卷 - 构成指定长度字符串的个数/字符串拼接(Java)

华为OD机试&#xff08;C卷D卷&#xff09;2024真题目录 题目描述&#xff1a;构成指定长度字符串的个数 (本题分值200) 给定 M&#xff08;0 < M ≤ 30&#xff09;个字符&#xff08;a-z&#xff09;&#xff0c;从中取出任意字符&#xff08;每个字符只能用一次&#x…

科普文:银行信贷系统概叙

信贷业务流程 资金需求者提交申请&#xff1a;资金需求者通过不同渠道&#xff08;如APP、网站、门店等&#xff09;提交贷款申请。 系统交互完成审批&#xff1a;系统通过自动化和人工相结合的方式&#xff0c;对贷款申请进行初步筛选和审批。 系统交互完成策略判断&#xf…

rsync文件远程同步

目录 一、什么是rsync远程同步 二、实操rsync远程文件同步 1、配置rsync同步源 2、客户端部署 3、增量备份​编辑 4、删除文件 5、如何实现免交互登录 6、crontab rsync 实现定时同步 7、使用ssh实现rsync数据同步【☆】 如何使用ssh免交互实现数据同步&#xff1f;…

Golang | Leetcode Golang题解之第260题只出现一次的数字III

题目&#xff1a; 题解&#xff1a; func singleNumber(nums []int) []int {xorSum : 0for _, num : range nums {xorSum ^ num}lsb : xorSum & -xorSumtype1, type2 : 0, 0for _, num : range nums {if num&lsb > 0 {type1 ^ num} else {type2 ^ num}}return []in…

【深度学习入门篇 ⑨】循环神经网络实战

【&#x1f34a;易编橙&#xff1a;一个帮助编程小伙伴少走弯路的终身成长社群&#x1f34a;】 大家好&#xff0c;我是小森( &#xfe61;ˆoˆ&#xfe61; ) &#xff01; 易编橙终身成长社群创始团队嘉宾&#xff0c;橙似锦计划领衔成员、阿里云专家博主、腾讯云内容共创官…

【一刷《剑指Offer》】面试题 48:不能被继承的类

《剑指Offer》对应内容&#xff1a; 可参考&#xff1a; 【C】继承 -- 详解_c,两个派生类继承一个基类,声明对象的时候用基类的对象。-CSDN博客