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

1、index.xml

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

XML 复制代码
<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:clipToPadding="false" />

</LinearLayout>

2、item_linear_layout.xml

item的布局文件

XML 复制代码
<FrameLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <LinearLayout
            android:id="@+id/container"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#FFFFFF"
            android:backgroundTint="#80FFFFFF"
            android:outlineProvider="background"
            android:orientation="vertical">
            <!-- 在这里可以放一些固定内容 -->
        </LinearLayout>

    </FrameLayout>

3、RecyclerViewAdapter.java

java 复制代码
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

    private List<LinearLayout> linearLayouts = new ArrayList<>();

    private int[] data;

    public void updateData(int[] newData) {
        this.data = newData;
        Logger.d("updateData");
        notifyDataSetChanged(); // 通知RecyclerView刷新
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view = inflater.inflate(R.layout.item_linear_layout, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        LinearLayout linearLayout = linearLayouts.get(position);
        holder.bind(linearLayout);
    }

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

    public void addLinearLayout(LinearLayout linearLayout, int i) {
        linearLayouts.add(linearLayout);
        notifyItemInserted(linearLayouts.size() - 1);
    }

    static class ViewHolder extends RecyclerView.ViewHolder {

        LinearLayout container;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            container = itemView.findViewById(R.id.container);
        }

        public void bind(LinearLayout linearLayout) {
            ViewGroup container = itemView.findViewById(R.id.container);
            if (linearLayout.getParent() != null) {
                ((ViewGroup) linearLayout.getParent()).removeView(linearLayout);
            }
            container.removeAllViews();
            container.addView(linearLayout);
        }
    }
}

3、LayoutHelper

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

java 复制代码
public static RecyclerViewAdapter adapter;
    public static TextView []textViews;
    public static ImageView []dotImages;
    public static LinearLayout []innerLinearLayouts;
    public static int len = 22;
    public static void setupWasherLayout(Context context, RecyclerView recyclerView) {
        recyclerView.setLayoutManager(new GridLayoutManager(context, 4));

         adapter = new RecyclerViewAdapter();
        recyclerView.setAdapter(adapter);
        int []arr = {1,0,1,0,0,1,2,0,1,0,2,1,0,0,1,0,0,0,1,2,0,0};
        textViews = new TextView[len];
        dotImages = new ImageView[len];
        innerLinearLayouts = new LinearLayout[len];
        for (int i = 0; i < arr.length; i++) {
            LinearLayout innerLinearLayout = createWasherItemLayout(context, i,arr[i]);
            adapter.addLinearLayout(innerLinearLayout, i);
        }
    }

    private static LinearLayout createWasherItemLayout(Context context, final int index, final int status) {
        // 创建一个外层LinearLayout,垂直布局
        final LinearLayout innerLinearLayout = new LinearLayout(context);
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                200,  // 设置宽度为200dp
                100   // 设置高度为100dp
        );
        layoutParams.setMargins(20, 20, 20, 20); // 设置间距
        innerLinearLayout.setLayoutParams(layoutParams);
        innerLinearLayout.setOrientation(LinearLayout.HORIZONTAL); // 垂直布局
        innerLinearLayout.setBackgroundColor(Color.parseColor("#987988"));

        // 设置背景颜色并包含透明度
        int backgroundColorWithAlpha = Color.argb(50, 152, 121, 136); // 128 表示透明度
        innerLinearLayout.setBackgroundColor(backgroundColorWithAlpha);

        // 添加一个ImageView来显示本地图片
        final ImageView imageView = new ImageView(context);
        imageView.setLayoutParams(new LinearLayout.LayoutParams(
                60,  // 设置宽度为60dp
                80   // 设置高度为80dp
        ));
        imageView.setImageResource(R.mipmap.washer_item); // 替换为你的图片资源

        // 添加一个TextView来显示洗衣机编号
        final TextView textView = new TextView(context);
        textView.setText((index + 1) + "号洗衣机");
        textView.setTypeface(null, Typeface.BOLD); // 设置文本加粗
        LinearLayout.LayoutParams textLayoutParams = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,  // 宽度包裹内容
                LinearLayout.LayoutParams.WRAP_CONTENT   // 高度包裹内容
        );
        textLayoutParams.setMargins(10, 0, 0, 0); // 设置左边边距
        textView.setLayoutParams(textLayoutParams);

        // 创建一个垂直的LinearLayout来包含"故障"文本和圆点图片
        final LinearLayout infoLayout = new LinearLayout(context);
        infoLayout.setOrientation(LinearLayout.VERTICAL);

        // 创建一个水平的LinearLayout来包含"故障"文本和圆点图片
        final LinearLayout statusLayout = new LinearLayout(context);
        statusLayout.setOrientation(LinearLayout.HORIZONTAL);

        // 添加圆点图片
        final ImageView dotImage = new ImageView(context);
        LinearLayout.LayoutParams dotImageParams = new LinearLayout.LayoutParams(
                10,  // 设置宽度为10dp
                10   // 设置高度为10dp
        );
        dotImageParams.setMargins(0, 0, 5, 0);
        dotImage.setLayoutParams(dotImageParams);
        // 添加圆点图片到statusLayout
        statusLayout.addView(dotImage);
        // 添加文本
        final TextView statusText = new TextView(context);

        // 添加文本到statusLayout
        statusLayout.addView(statusText);
        textViews[index] = statusText;
        dotImages[index] = dotImage;
        // 添加ImageView和TextView到innerLinearLayout
        innerLinearLayout.addView(imageView);
        infoLayout.addView(textView);
        infoLayout.addView(statusLayout);
        innerLinearLayout.addView(infoLayout);

        // 设置innerLinearLayout水平和垂直居中
        innerLinearLayout.setGravity(Gravity.CENTER);
        statusLayout.setGravity(Gravity.CENTER);
        innerLinearLayouts[index] = innerLinearLayout;
        // 在这里更新图片和文本
        updateStatusViews(status, index,context);
        // 为innerLinearLayout添加点击事件监听器
        return innerLinearLayout;
    }

    // todo 更新状态视图
    private static void updateStatusViews(int status,int index,Context context) {
        switch (status){
            case 0:
                dotImages[index].setImageResource(R.mipmap.grey_dot);
                textViews[index].setText("空闲");

                break;
            case 1:
                dotImages[index].setImageResource(R.mipmap.green_dot);
                textViews[index].setText("使用中");
                break;
            case 2:
                dotImages[index].setImageResource(R.mipmap.red_dot);
                textViews[index].setText("设备故障");
                break;
            default:
        }
        innerLinearLayouts[index].setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                switch (status){
                    case 0:
                        Intent intent = new Intent();
                        intent.setClass(context, WasherActivity.class);
                        context.startActivity(intent);
                        break;
                    case 1:
                        Toast.makeText(context, "被人用啦~", Toast.LENGTH_SHORT).show();
                        break;
                    case 2:
                        Toast.makeText(context, (index + 1) + " 号洗衣机连接错误", Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        Toast.makeText(context, (index + 1) + " 号洗衣机连接错误", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
相关推荐
zhangphil5 小时前
Android绘图Path基于LinearGradient线性动画渐变,Kotlin(2)
android·kotlin
watl05 小时前
【Android】unzip aar删除冲突classes再zip
android·linux·运维
键盘上的蚂蚁-5 小时前
PHP爬虫类的并发与多线程处理技巧
android
喜欢猪猪6 小时前
Java技术专家视角解读:SQL优化与批处理在大数据处理中的应用及原理
android·python·adb
JasonYin~8 小时前
HarmonyOS NEXT 实战之元服务:静态案例效果---手机查看电量
android·华为·harmonyos
zhangphil8 小时前
Android adb查看某个进程的总线程数
android·adb
抛空8 小时前
Android14 - SystemServer进程的启动与工作流程分析
android
Gerry_Liang10 小时前
记一次 Android 高内存排查
android·性能优化·内存泄露·mat
天天打码11 小时前
ThinkPHP项目如何关闭runtime下Log日志文件记录
android·java·javascript
爱数学的程序猿14 小时前
Python入门:6.深入解析Python中的序列
android·服务器·python