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();
}
}
});
}