• Android渲染一个列表的过程,并提供动态改变样式


    1、index.xml

    布局文件,我省略了其他代码,我们需要recyclerview保证在规定范围内,如果列表元素过多可以滑动

    1. <LinearLayout
    2. android:layout_width="match_parent"
    3. android:layout_height="match_parent"
    4. android:layout_weight="1"
    5. android:orientation="vertical">
    6. <androidx.recyclerview.widget.RecyclerView
    7. android:id="@+id/recyclerView"
    8. android:layout_width="match_parent"
    9. android:layout_height="0dp"
    10. android:layout_weight="1"
    11. android:clipToPadding="false" />
    12. LinearLayout>

    2、item_linear_layout.xml

    item的布局文件

    1. <FrameLayout
    2. xmlns:android="http://schemas.android.com/apk/res/android"
    3. android:layout_width="wrap_content"
    4. android:layout_height="wrap_content">
    5. <LinearLayout
    6. android:id="@+id/container"
    7. android:layout_width="wrap_content"
    8. android:layout_height="wrap_content"
    9. android:background="#FFFFFF"
    10. android:backgroundTint="#80FFFFFF"
    11. android:outlineProvider="background"
    12. android:orientation="vertical">
    13. LinearLayout>
    14. FrameLayout>

    3、RecyclerViewAdapter.java

    1. public class RecyclerViewAdapter extends RecyclerView.Adapter {
    2. private List linearLayouts = new ArrayList<>();
    3. private int[] data;
    4. public void updateData(int[] newData) {
    5. this.data = newData;
    6. Logger.d("updateData");
    7. notifyDataSetChanged(); // 通知RecyclerView刷新
    8. }
    9. @NonNull
    10. @Override
    11. public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    12. LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    13. View view = inflater.inflate(R.layout.item_linear_layout, parent, false);
    14. return new ViewHolder(view);
    15. }
    16. @Override
    17. public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    18. LinearLayout linearLayout = linearLayouts.get(position);
    19. holder.bind(linearLayout);
    20. }
    21. @Override
    22. public int getItemCount() {
    23. return linearLayouts.size();
    24. }
    25. public void addLinearLayout(LinearLayout linearLayout, int i) {
    26. linearLayouts.add(linearLayout);
    27. notifyItemInserted(linearLayouts.size() - 1);
    28. }
    29. static class ViewHolder extends RecyclerView.ViewHolder {
    30. LinearLayout container;
    31. public ViewHolder(@NonNull View itemView) {
    32. super(itemView);
    33. container = itemView.findViewById(R.id.container);
    34. }
    35. public void bind(LinearLayout linearLayout) {
    36. ViewGroup container = itemView.findViewById(R.id.container);
    37. if (linearLayout.getParent() != null) {
    38. ((ViewGroup) linearLayout.getParent()).removeView(linearLayout);
    39. }
    40. container.removeAllViews();
    41. container.addView(linearLayout);
    42. }
    43. }
    44. }

    3、LayoutHelper

    我们可以把可能需要动态改变的元素保存到数组中,如textviews、dotImages、innerLinearLayouts,在我们动态创建时把各个元素存储到对应数组中,写一个updateStatusViews方法用于局部渲染,这样就不用大面积刷新了,当后端websocket推送更新消息时,直接调用就可以了

    1. public static RecyclerViewAdapter adapter;
    2. public static TextView []textViews;
    3. public static ImageView []dotImages;
    4. public static LinearLayout []innerLinearLayouts;
    5. public static int len = 22;
    6. public static void setupWasherLayout(Context context, RecyclerView recyclerView) {
    7. recyclerView.setLayoutManager(new GridLayoutManager(context, 4));//一行几个item
    8. adapter = new RecyclerViewAdapter();
    9. recyclerView.setAdapter(adapter);
    10. int []arr = {1,0,1,0,0,1,2,0,1,0,2,1,0,0,1,0,0,0,1,2,0,0};
    11. textViews = new TextView[len];
    12. dotImages = new ImageView[len];
    13. innerLinearLayouts = new LinearLayout[len];
    14. for (int i = 0; i < arr.length; i++) {
    15. LinearLayout innerLinearLayout = createWasherItemLayout(context, i,arr[i]);
    16. adapter.addLinearLayout(innerLinearLayout, i);
    17. }
    18. }
    19. private static LinearLayout createWasherItemLayout(Context context, final int index, final int status) {
    20. // 创建一个外层LinearLayout,垂直布局
    21. final LinearLayout innerLinearLayout = new LinearLayout(context);
    22. LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
    23. 200, // 设置宽度为200dp
    24. 100 // 设置高度为100dp
    25. );
    26. layoutParams.setMargins(20, 20, 20, 20); // 设置间距
    27. innerLinearLayout.setLayoutParams(layoutParams);
    28. innerLinearLayout.setOrientation(LinearLayout.HORIZONTAL); // 垂直布局
    29. innerLinearLayout.setBackgroundColor(Color.parseColor("#987988"));
    30. // 设置背景颜色并包含透明度
    31. int backgroundColorWithAlpha = Color.argb(50, 152, 121, 136); // 128 表示透明度
    32. innerLinearLayout.setBackgroundColor(backgroundColorWithAlpha);
    33. // 添加一个ImageView来显示本地图片
    34. final ImageView imageView = new ImageView(context);
    35. imageView.setLayoutParams(new LinearLayout.LayoutParams(
    36. 60, // 设置宽度为60dp
    37. 80 // 设置高度为80dp
    38. ));
    39. imageView.setImageResource(R.mipmap.washer_item); // 替换为你的图片资源
    40. // 添加一个TextView来显示洗衣机编号
    41. final TextView textView = new TextView(context);
    42. textView.setText((index + 1) + "号洗衣机");
    43. textView.setTypeface(null, Typeface.BOLD); // 设置文本加粗
    44. LinearLayout.LayoutParams textLayoutParams = new LinearLayout.LayoutParams(
    45. LinearLayout.LayoutParams.WRAP_CONTENT, // 宽度包裹内容
    46. LinearLayout.LayoutParams.WRAP_CONTENT // 高度包裹内容
    47. );
    48. textLayoutParams.setMargins(10, 0, 0, 0); // 设置左边边距
    49. textView.setLayoutParams(textLayoutParams);
    50. // 创建一个垂直的LinearLayout来包含“故障”文本和圆点图片
    51. final LinearLayout infoLayout = new LinearLayout(context);
    52. infoLayout.setOrientation(LinearLayout.VERTICAL);
    53. // 创建一个水平的LinearLayout来包含“故障”文本和圆点图片
    54. final LinearLayout statusLayout = new LinearLayout(context);
    55. statusLayout.setOrientation(LinearLayout.HORIZONTAL);
    56. // 添加圆点图片
    57. final ImageView dotImage = new ImageView(context);
    58. LinearLayout.LayoutParams dotImageParams = new LinearLayout.LayoutParams(
    59. 10, // 设置宽度为10dp
    60. 10 // 设置高度为10dp
    61. );
    62. dotImageParams.setMargins(0, 0, 5, 0);
    63. dotImage.setLayoutParams(dotImageParams);
    64. // 添加圆点图片到statusLayout
    65. statusLayout.addView(dotImage);
    66. // 添加文本
    67. final TextView statusText = new TextView(context);
    68. // 添加文本到statusLayout
    69. statusLayout.addView(statusText);
    70. textViews[index] = statusText;
    71. dotImages[index] = dotImage;
    72. // 添加ImageView和TextView到innerLinearLayout
    73. innerLinearLayout.addView(imageView);
    74. infoLayout.addView(textView);
    75. infoLayout.addView(statusLayout);
    76. innerLinearLayout.addView(infoLayout);
    77. // 设置innerLinearLayout水平和垂直居中
    78. innerLinearLayout.setGravity(Gravity.CENTER);
    79. statusLayout.setGravity(Gravity.CENTER);
    80. innerLinearLayouts[index] = innerLinearLayout;
    81. // 在这里更新图片和文本
    82. updateStatusViews(status, index,context);
    83. // 为innerLinearLayout添加点击事件监听器
    84. return innerLinearLayout;
    85. }
    86. // todo 更新状态视图
    87. private static void updateStatusViews(int status,int index,Context context) {
    88. switch (status){
    89. case 0:
    90. dotImages[index].setImageResource(R.mipmap.grey_dot);
    91. textViews[index].setText("空闲");
    92. break;
    93. case 1:
    94. dotImages[index].setImageResource(R.mipmap.green_dot);
    95. textViews[index].setText("使用中");
    96. break;
    97. case 2:
    98. dotImages[index].setImageResource(R.mipmap.red_dot);
    99. textViews[index].setText("设备故障");
    100. break;
    101. default:
    102. }
    103. innerLinearLayouts[index].setOnClickListener(new View.OnClickListener(){
    104. @Override
    105. public void onClick(View view) {
    106. switch (status){
    107. case 0:
    108. Intent intent = new Intent();
    109. intent.setClass(context, WasherActivity.class);
    110. context.startActivity(intent);
    111. break;
    112. case 1:
    113. Toast.makeText(context, "被人用啦~", Toast.LENGTH_SHORT).show();
    114. break;
    115. case 2:
    116. Toast.makeText(context, (index + 1) + " 号洗衣机连接错误", Toast.LENGTH_SHORT).show();
    117. break;
    118. default:
    119. Toast.makeText(context, (index + 1) + " 号洗衣机连接错误", Toast.LENGTH_SHORT).show();
    120. }
    121. }
    122. });
    123. }

  • 相关阅读:
    git 设置ignore文件
    【memcpy函数的介绍与使用和模拟实现】
    ROS编译 调用第三方动态库(xxx.so)
    备忘录模式简介
    flutter背景图片设置
    STL——map && set
    接口自动化测试小结
    风储联合系统的仿真模型研究
    浅谈MySQL执行计划Explain
    ES7~11学习48~68
  • 原文地址:https://blog.csdn.net/m0_49083276/article/details/133919066