本意是解决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); } } } }
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>
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>
另外碰到了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")
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
2021-12-29 CodeForces - 607B Zuma