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();
                }
            }
        });
    }
相关推荐
似霰1 小时前
安卓智能指针sp、wp、RefBase浅析
android·c++·binder
大风起兮云飞扬丶1 小时前
Android——网络请求
android
干一行,爱一行1 小时前
android camera data -> surface 显示
android
断墨先生1 小时前
uniapp—android原生插件开发(3Android真机调试)
android·uni-app
无极程序员3 小时前
PHP常量
android·ide·android studio
萌面小侠Plus4 小时前
Android笔记(三十三):封装设备性能级别判断工具——低端机还是高端机
android·性能优化·kotlin·工具类·低端机
慢慢成长的码农4 小时前
Android Profiler 内存分析
android
大风起兮云飞扬丶4 小时前
Android——多线程、线程通信、handler机制
android
L72564 小时前
Android的Handler
android
清风徐来辽4 小时前
Android HandlerThread 基础
android