带有 RecyclerView 的自定义 AlertDialog - 列表始终为空
Custom AlertDialog with RecyclerView - list is always empty
首先,我使用 RecyclerView 创建了 activity,它工作正常。我的原码:
activity_agreements.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:paddingTop="8dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toTopOf="@+id/editText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:ems="10"
android:gravity="left"
android:inputType="none|text|textPersonName"
android:text="* required fields"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/btnGetSelected"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<Button
android:id="@+id/btnGetSelected"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_marginBottom="4dp"
android:text="I agree"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
</android.support.constraint.ConstraintLayout>
传递给 ActivityAgreements 和适配器设置的协议列表:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_agreements);
btnGetSelected = findViewById(R.id.btnGetSelected);
list = findViewById(R.id.list);
list.setLayoutManager(new LinearLayoutManager(this));
list.setHasFixedSize(true);
agreements = getIntent().getParcelableArrayListExtra("agreements");
AgreementsAdapter adapter = new AgreementsAdapter(this.agreements);
list.setAdapter(adapter);
我的适配器代码:
public class AgreementsAdapter extends RecyclerView.Adapter<AgreementsAdapter.ViewHolder>
{
ArrayList<Agreement> agreements;
public AgreementsAdapter(List<Agreement> agreements)
{
this.agreements = new ArrayList<>(agreements);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.agreement_list_item, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position)
{
holder.bindData(agreements.get(position));
holder.checkbox.setOnCheckedChangeListener(null);
holder.checkbox.setChecked(agreements.get(position).getAccepted());
//holder.checkbox.setFloorUnCheckedColor(agreements.get(position).getRequired()? Color.rgb(255,0,0):Color.rgb(0,255,0) );
holder.checkbox.setOnCheckedChangeListener((buttonView, isChecked) -> agreements.get(holder.getAdapterPosition()).setAccepted(isChecked));
}
@Override
public int getItemCount()
{
return agreements.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder
{
private TextView textAgreementName;
private AppCompatCheckBox checkbox;
public ViewHolder(View v)
{
super(v);
//textAgreementName = v.findViewById(R.id.text_agreement_name);
checkbox = v.findViewById(R.id.checkbox_agreement_accepted);
}
public void bindData(Agreement agreement)
{
//checkbox.setFloorUnCheckedColor(agreement.getRequired()? Color.rgb(255,0,0):Color.rgb(0,0,255) );
/*if(agreement.getRequired())
{
textAgreementName.setTypeface(null, Typeface.BOLD);
textAgreementName.setText(agreement.getName() + " *");
}
else
textAgreementName.setText(agreement.getName());*/
if(agreement.getRequired())
{
checkbox.setText(agreement.getName() + " *");
checkbox.setTypeface(null, Typeface.BOLD);
}
else
{
checkbox.setText(agreement.getName());
}
}
}
}
一切正常,activity 列表显示本身没有任何问题。现在,我想使用 AlertDialog,而不是 activity 来显示协议列表。我正在尝试以这种方式创建 AlertDialog(在 main activity 中):
AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
LayoutInflater inflater = getLayoutInflater();
View convertView = inflater.inflate(R.layout.activity_agreements, null);
alertDialog.setView(convertView);
RecyclerView list = convertView.findViewById(R.id.list);
list.setLayoutManager(new LinearLayoutManager(this));
list.setHasFixedSize(true);
AgreementsAdapter adapter = new AgreementsAdapter(agreements);
list.setAdapter(adapter);
alertDialog.show();
agreements
变量包含协议列表(与之前传递给 AgrrementsActivity 的相同)。但它不起作用 - 对话框以自定义布局显示,但列表始终为空。
谁能指出我遗漏了什么?
固定大小的新代码和其他建议:
AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
LayoutInflater inflater = getLayoutInflater();
View convertView = inflater.inflate(R.layout.activity_agreements, null);
RecyclerView list = convertView.findViewById(R.id.list);
list.setLayoutManager(new LinearLayoutManager(this));
list.setHasFixedSize(true);
AgreementsAdapter adapter = new AgreementsAdapter(agreements);
list.setAdapter(adapter);
alertDialog.setView(convertView);
AlertDialog dialog = alertDialog.create();
dialog.getWindow().setLayout(600, 400);
dialog.show();
adapter.notifyDataSetChanged();
您的 RecyclerView 可能正在显示列表,但它的高度为 0,所以它看起来是空的。
对话框大小有点棘手,检查 this answer 并尝试给它一个固定的高度(可能是屏幕高度的百分比)。
我知道现在回答这个问题已经很晚了,但我也遇到过同样的问题。所以对于仍然面临这个问题的人可以使用下面的技术。
如果您正在使用 具有约束布局的 Recycler 视图 并且在警报对话框中设置了 layout_height="0"
那么您将无法看到回收器视图列表。要解决此问题,请设置此
app:layout_constraintHeight_default="wrap"
在 recyclerview
下班后寻找使用 RecyclerView 和 AlertDialog 以及 ConstraintLayout 的最佳方法,解决方案:
<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="match_parent">
<TextView
android:id="@+id/abc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintHeight_default="wrap"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/abc" />
<ProgressBar
android:id="@+id/progressBarFavorito"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/abc" />
对于在 alertdialogue 中使用 recyclerview,你应该有点 tricky.As 你使用匹配父项,所以 recyclerview 的宽度为 0 因为 recyclerviews 维度是在 alertdialogue 之前设置的 created.So 你这样做:
1) 使用 runnable 并设置你的适配器(或我们用 recyclerview 做的其他活动)延迟 1 秒
或者,
2)当你初始化recyclerview时,然后只需以编程方式设置它的layoutparams。这解决了我的问题。(不要盲目使用此代码,我只是从我的代码中复制它,它可能不适合您one.rather 了解一下这个问题。)
member_list.setLayoutParams(new ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
首先,我使用 RecyclerView 创建了 activity,它工作正常。我的原码:
activity_agreements.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:paddingTop="8dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toTopOf="@+id/editText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:ems="10"
android:gravity="left"
android:inputType="none|text|textPersonName"
android:text="* required fields"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/btnGetSelected"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<Button
android:id="@+id/btnGetSelected"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_marginBottom="4dp"
android:text="I agree"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
</android.support.constraint.ConstraintLayout>
传递给 ActivityAgreements 和适配器设置的协议列表:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_agreements);
btnGetSelected = findViewById(R.id.btnGetSelected);
list = findViewById(R.id.list);
list.setLayoutManager(new LinearLayoutManager(this));
list.setHasFixedSize(true);
agreements = getIntent().getParcelableArrayListExtra("agreements");
AgreementsAdapter adapter = new AgreementsAdapter(this.agreements);
list.setAdapter(adapter);
我的适配器代码:
public class AgreementsAdapter extends RecyclerView.Adapter<AgreementsAdapter.ViewHolder>
{
ArrayList<Agreement> agreements;
public AgreementsAdapter(List<Agreement> agreements)
{
this.agreements = new ArrayList<>(agreements);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.agreement_list_item, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position)
{
holder.bindData(agreements.get(position));
holder.checkbox.setOnCheckedChangeListener(null);
holder.checkbox.setChecked(agreements.get(position).getAccepted());
//holder.checkbox.setFloorUnCheckedColor(agreements.get(position).getRequired()? Color.rgb(255,0,0):Color.rgb(0,255,0) );
holder.checkbox.setOnCheckedChangeListener((buttonView, isChecked) -> agreements.get(holder.getAdapterPosition()).setAccepted(isChecked));
}
@Override
public int getItemCount()
{
return agreements.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder
{
private TextView textAgreementName;
private AppCompatCheckBox checkbox;
public ViewHolder(View v)
{
super(v);
//textAgreementName = v.findViewById(R.id.text_agreement_name);
checkbox = v.findViewById(R.id.checkbox_agreement_accepted);
}
public void bindData(Agreement agreement)
{
//checkbox.setFloorUnCheckedColor(agreement.getRequired()? Color.rgb(255,0,0):Color.rgb(0,0,255) );
/*if(agreement.getRequired())
{
textAgreementName.setTypeface(null, Typeface.BOLD);
textAgreementName.setText(agreement.getName() + " *");
}
else
textAgreementName.setText(agreement.getName());*/
if(agreement.getRequired())
{
checkbox.setText(agreement.getName() + " *");
checkbox.setTypeface(null, Typeface.BOLD);
}
else
{
checkbox.setText(agreement.getName());
}
}
}
}
一切正常,activity 列表显示本身没有任何问题。现在,我想使用 AlertDialog,而不是 activity 来显示协议列表。我正在尝试以这种方式创建 AlertDialog(在 main activity 中):
AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
LayoutInflater inflater = getLayoutInflater();
View convertView = inflater.inflate(R.layout.activity_agreements, null);
alertDialog.setView(convertView);
RecyclerView list = convertView.findViewById(R.id.list);
list.setLayoutManager(new LinearLayoutManager(this));
list.setHasFixedSize(true);
AgreementsAdapter adapter = new AgreementsAdapter(agreements);
list.setAdapter(adapter);
alertDialog.show();
agreements
变量包含协议列表(与之前传递给 AgrrementsActivity 的相同)。但它不起作用 - 对话框以自定义布局显示,但列表始终为空。
谁能指出我遗漏了什么?
固定大小的新代码和其他建议:
AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
LayoutInflater inflater = getLayoutInflater();
View convertView = inflater.inflate(R.layout.activity_agreements, null);
RecyclerView list = convertView.findViewById(R.id.list);
list.setLayoutManager(new LinearLayoutManager(this));
list.setHasFixedSize(true);
AgreementsAdapter adapter = new AgreementsAdapter(agreements);
list.setAdapter(adapter);
alertDialog.setView(convertView);
AlertDialog dialog = alertDialog.create();
dialog.getWindow().setLayout(600, 400);
dialog.show();
adapter.notifyDataSetChanged();
您的 RecyclerView 可能正在显示列表,但它的高度为 0,所以它看起来是空的。
对话框大小有点棘手,检查 this answer 并尝试给它一个固定的高度(可能是屏幕高度的百分比)。
我知道现在回答这个问题已经很晚了,但我也遇到过同样的问题。所以对于仍然面临这个问题的人可以使用下面的技术。
如果您正在使用 具有约束布局的 Recycler 视图 并且在警报对话框中设置了 layout_height="0"
那么您将无法看到回收器视图列表。要解决此问题,请设置此
app:layout_constraintHeight_default="wrap"
在 recyclerview
下班后寻找使用 RecyclerView 和 AlertDialog 以及 ConstraintLayout 的最佳方法,解决方案:
<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="match_parent">
<TextView
android:id="@+id/abc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintHeight_default="wrap"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/abc" />
<ProgressBar
android:id="@+id/progressBarFavorito"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/abc" />
对于在 alertdialogue 中使用 recyclerview,你应该有点 tricky.As 你使用匹配父项,所以 recyclerview 的宽度为 0 因为 recyclerviews 维度是在 alertdialogue 之前设置的 created.So 你这样做:
1) 使用 runnable 并设置你的适配器(或我们用 recyclerview 做的其他活动)延迟 1 秒
或者, 2)当你初始化recyclerview时,然后只需以编程方式设置它的layoutparams。这解决了我的问题。(不要盲目使用此代码,我只是从我的代码中复制它,它可能不适合您one.rather 了解一下这个问题。)
member_list.setLayoutParams(new ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));