【发布时间】:2020-10-13 13:11:18
【问题描述】:
我在 Android Studio 的一个项目中工作,该项目有一个问答游戏,其中有图像或文本作为答案选项,具体取决于问题(两者都只是 xml 文件中的按钮)。目前这些按钮显示在 2 列中,但如果按钮显示文本而不是图像,则列数应为 1,因为按钮大小必须更宽才能显示整个文本。
在我的适配器中,onBindViewHolder 获取答案选项列表并根据选项类型(图像/文本)设置按钮内容。对于一些测试,我创建了 RecylerView 的子类 AutofitRecyclerView 来自动计算列数,但这并没有解决我的问题。在 AutofitRecyclerView 中,我定义了一个 CenteredGridLayoutManager。此外,我尝试了 setSpanSizeLookup 方法,但这也没有帮助。
AutofitRecyclerView:
public class AutofitRecyclerView extends RecyclerView {
private GridLayoutManager manager;
private int columnWidth = -1;
public AutofitRecyclerView(Context context) {
super(context);
init(context, null);
}
public AutofitRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public AutofitRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
if (attrs != null) {
int[] attrsArray = {
android.R.attr.columnWidth
};
TypedArray array = context.obtainStyledAttributes(attrs, attrsArray);
columnWidth = array.getDimensionPixelSize(0, -1);
array.recycle();
}
manager = new CenteredGridLayoutManager(getContext(), 1);
setLayoutManager(manager);
}
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
super.onMeasure(widthSpec, heightSpec);
if (columnWidth > 0) {
int spanCount = Math.max(1, getMeasuredWidth() / columnWidth);
manager.setSpanCount(spanCount);
}
}
private class CenteredGridLayoutManager extends GridLayoutManager {
public CenteredGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public CenteredGridLayoutManager(Context context, int spanCount) {
super(context, spanCount);
}
public CenteredGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
super(context, spanCount, orientation, reverseLayout);
}
@Override
public int getPaddingLeft() {
final int totalItemWidth = columnWidth * getSpanCount();
if (totalItemWidth >= AutofitRecyclerView.this.getMeasuredWidth()) {
return super.getPaddingLeft(); // do nothing
} else {
return Math.round((AutofitRecyclerView.this.getMeasuredWidth() / (1f + getSpanCount())) - (totalItemWidth / (1f + getSpanCount())));
}
}
@Override
public int getPaddingRight() {
return getPaddingLeft();
}
}
}
按钮-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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="14dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout_imgButton"
android:layout_width="125dp"
android:layout_height="125dp"
android:layout_marginBottom="0dp"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<Button
android:id="@+id/option_imgButton"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="1dp"
android:layout_marginTop="1dp"
android:layout_marginEnd="1dp"
android:layout_marginBottom="1dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="@string/game_choose_answer_option_button_placeholder_text"
app:layout_constraintBottom_toBottomOf="@id/constraintLayout_imgButton"
app:layout_constraintEnd_toEndOf="@id/constraintLayout_imgButton"
app:layout_constraintStart_toStartOf="@id/constraintLayout_imgButton"
app:layout_constraintTop_toTopOf="@id/constraintLayout_imgButton" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout_txtButton"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_marginBottom="0dp"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp"
android:layout_gravity="fill_horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<Button
android:id="@+id/option_textButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="1dp"
android:layout_marginTop="1dp"
android:layout_marginEnd="1dp"
android:layout_marginBottom="1dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:background="@drawable/button_background"
android:elevation="4dp"
android:fontFamily="@font/freude"
android:stateListAnimator="@null"
android:text="@string/game_choose_answer_option_button_placeholder_text"
android:textAppearance="@style/TextAppearance.Compat.Notification.Title.Media"
android:textColor="@color/forest"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="@id/constraintLayout_txtButton"
app:layout_constraintEnd_toEndOf="@id/constraintLayout_txtButton"
app:layout_constraintStart_toStartOf="@id/constraintLayout_txtButton"
app:layout_constraintTop_toTopOf="@id/constraintLayout_txtButton" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Recyclerview-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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="de.lmu.treeapp.activities.minigames.chooseAnswer.GameActivity_ChooseAnswer">
<TextView
android:id="@+id/game_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="25dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:text="@string/game_description_placeholder"
app:layout_constraintTop_toTopOf="@+id/guideline_top"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="0.04" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.02" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.98" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.02" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_mid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.3" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_bot"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.98" />
<de.lmu.treeapp.activities.minigames.chooseAnswer.AutofitRecyclerView
android:id="@+id/auto_fit_recycler_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="10dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="20dp"
android:clipToPadding="false"
android:columnWidth="150dp"
android:numColumns="auto_fit"
app:layout_constraintBottom_toBottomOf="@id/guideline_bot"
app:layout_constraintEnd_toEndOf="@id/guideline_right"
app:layout_constraintStart_toStartOf="@id/guideline_left"
app:layout_constraintTop_toBottomOf="@+id/guideline_mid" />
</androidx.constraintlayout.widget.ConstraintLayout>
我现在还没有看到什么?为 2 个不同的按钮提供 2 个不同的 xml 布局可能会更好,但我不知道如何告诉我的 recyclerView 它必须采用哪个布局 xml。
【问题讨论】:
标签: android android-layout android-recyclerview gridlayoutmanager