RecyclerView动态添加item背景

Posted on   Capterlliar  阅读(10)  评论(0编辑  收藏  举报

本意是解决RecyclerView动态添加背景后item高度不正确的bug。一开始以为是RecyclerView的问题,后来发现是background.xml多加了padding。把背景xml的padding删掉后就正常了。但demo写都写了存一下吧。

需求:根据item在RecyclerView的不同位置添加不同背景。

解:给RecyclerView写一个adapter,通过重载onBindViewHolder设置背景。

MainActivity.java

复制代码
package com.example.myapplication;

import android.os.Bundle;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.activity.EdgeToEdge;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.myapplication.MainActivity.CatsRecyclerViewAdapter.CatViewHolder;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

  private CatsRecyclerViewAdapter catsRecyclerViewAdapter;

  @Override
  protected 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;
    });

    RecyclerView recyclerView = findViewById(R.id.cats_recycler_view);
    catsRecyclerViewAdapter = new CatsRecyclerViewAdapter();
    final LinearLayoutManager catsLayoutManager = new LinearLayoutManager(this);
    recyclerView.setAdapter(catsRecyclerViewAdapter);
    recyclerView.setLayoutManager(catsLayoutManager);

    Button button = findViewById(R.id.button);
    button.setOnClickListener(view -> catsRecyclerViewAdapter.updateItems("miao"));
  }

  static class CatsRecyclerViewAdapter extends RecyclerView.Adapter<CatViewHolder> {

    private final List<String> catEntities;

    CatsRecyclerViewAdapter() {
      this.catEntities = new ArrayList<>();
    }

    @NonNull
    @Override
    public CatViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
      int resId = R.layout.cats_view_item;
      return new CatViewHolder(
          LayoutInflater.from(viewGroup.getContext()).inflate(resId, viewGroup, false));
    }

    @Override
    public void onBindViewHolder(@NonNull CatViewHolder holder, int i) {
      holder.bind(catEntities.get(i));

      // holder.holderView.setPaddingRelative(0, 0, 0, 0);
      @DrawableRes int backgroundRes = getExpressivePreferenceBackgroundRes(i, getItemCount());
      holder.holderView.setBackgroundResource(backgroundRes);
    }

    @Override
    public int getItemCount() {
      return catEntities == null ? 0 : catEntities.size();
    }

    public @DrawableRes int getExpressivePreferenceBackgroundRes(int pos, int total) {
      @DrawableRes int backgroundRes;
      if (total == 1) {
        backgroundRes = R.drawable.background;
      } else if (pos == 0) {
        backgroundRes = R.drawable.background_top;
      } else if (pos == total - 1) {
        backgroundRes = R.drawable.background_bottom;
      } else {
        backgroundRes = R.drawable.background_center;
      }
      return backgroundRes;
    }

    void updateItems(String text) {
      this.catEntities.add(text);
      notifyDataSetChanged();
    }

    static class CatViewHolder extends RecyclerView.ViewHolder {
      private final LinearLayout holderView;
      private final TextView catSource;
      public CatViewHolder(@NonNull View itemView) {
        super(itemView);
        holderView = (LinearLayout) itemView;
        catSource = itemView.findViewById(R.id.cats_source_text);
      }

      void bind(String text) {
        catSource.setText(text);
      }
    }
  }
}
View Code
复制代码

activity_main.xml

复制代码
<?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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/cats_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginHorizontal="16dp"
        android:nestedScrollingEnabled="false"/>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="click me">
    </Button>

  </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
View Code
复制代码

background.xml

复制代码
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:colorControlHighlight">
    <item
        android:top="2dp">
        <shape android:shape="rectangle">
            <solid
                android:color="@color/material_dynamic_tertiary90" />
            <corners
                android:radius="20dp" />
        </shape>
    </item>
</ripple>
View Code
复制代码

 

另外碰到了gradle的一个报错: 2 files found with path 'META-INF/androidx.localbroadcastmanager_localbroadcastmanager.version'.

原因是一开始用的android support的RecycleView,android support和androidx不兼容,都改成androidx就好了。

build.gradle.kt

复制代码
plugins {
  alias(libs.plugins.android.application)
}

android {
  namespace = "com.example.myapplication"
  compileSdk = 34

  defaultConfig {
    applicationId = "com.example.myapplication"
    minSdk = 28
    targetSdk = 34
    versionCode = 1
    versionName = "1.0"

    testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
  }

  buildTypes {
    release {
      isMinifyEnabled = false
      proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
    }
  }
  compileOptions {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
  }
}

dependencies {
  implementation("androidx.appcompat:appcompat:1.1.0")
  implementation(libs.material)
  implementation("androidx.constraintlayout:constraintlayout:1.1.3")
  implementation("androidx.recyclerview:recyclerview:1.1.0")
}
View Code
复制代码

 

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
历史上的今天:
2021-12-29 CodeForces - 607B Zuma
点击右上角即可分享
微信分享提示