每次旋转设备时,Android-RecyclerView都会自我倍增
我有一个应用程序活动的横向配置。此活动包含一个片段,此片段包含一个textview和一个recyclerview。每次我在纵向和横向模式之间切换时,recyclerview都会留下自己的视图,就像我打开设备之前一样。这可能有点难理解我想问什么,所以我录了一张gif 这是我的活动每次旋转设备时,Android-RecyclerView都会自我倍增,android,android-recyclerview,Android,Android Recyclerview,我有一个应用程序活动的横向配置。此活动包含一个片段,此片段包含一个textview和一个recyclerview。每次我在纵向和横向模式之间切换时,recyclerview都会留下自己的视图,就像我打开设备之前一样。这可能有点难理解我想问什么,所以我录了一张gif 这是我的活动 public class RecipeStepsActivity extends AppCompatActivity { static Recipe recipe; @Override protected void
public class RecipeStepsActivity extends AppCompatActivity {
static Recipe recipe;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipe_steps);
if (StepDetailActivity.SDA_TAG.equals(StepDetailActivity.NEGATIVE))
recipe = getIntent().getParcelableExtra("recipe");
Bundle b = new Bundle();
b.putParcelable("recipe", recipe);
ActionBar ab = getSupportActionBar();
if (ab != null)
ab.setTitle(recipe.getName());
RecipeStepsFragment recipeStepsFragment = new RecipeStepsFragment();
recipeStepsFragment.setArguments(b);
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().add(R.id.frame_layout_steps, recipeStepsFragment).commit();
}
}
这是我的片段
public class RecipeStepsFragment extends Fragment {
@BindView(R.id.recipe_steps_rv)
RecyclerView recyclerView;
@BindView(R.id.ingredients_tv)
TextView tv_ingredients;
List<Step> steps;
public RecipeStepsFragment(){}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_recipe_steps, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ButterKnife.bind(this, view);
List<Ingredients> ingredients;
Recipe recipe = getArguments().getParcelable("recipe");
steps = recipe.getSteps();
initRecyclerView();
ingredients = recipe.getIngredients();
String ingredientsAppended = "INGREDIENTS" + "\n\n";
if (ingredients == null){
ingredientsAppended = "Not Available";
} else {
for (int a = 0 ; a < ingredients.size() ; a++) {
Ingredients i = ingredients.get(a);
ingredientsAppended += String.valueOf(i.getQuantity()) + " " +
i.getMeasure() + " " +
i.getIngredient();
if (a+1 != ingredients.size()){
ingredientsAppended += '\n';
}
}
}
tv_ingredients.setText(ingredientsAppended);
if(savedInstanceState != null){
recyclerView.scrollToPosition(savedInstanceState.getInt("position"));
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
outState.putInt("position", recyclerView.getVerticalScrollbarPosition());
super.onSaveInstanceState(outState);
}
private void initRecyclerView(){
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL));
RecipeStepsRecyclerAdapter recipeStepsRecyclerAdapter =
new RecipeStepsRecyclerAdapter(steps, new RecipeStepsRecyclerAdapter.ClickListener() {
@Override
public void onItemClick(int clickedItemPosition) {
Intent intentToStepDetail = new Intent(getActivity(), StepDetailActivity.class);
Step step = steps.get(clickedItemPosition);
intentToStepDetail.putExtra("step", step);
startActivity(intentToStepDetail);
}
}, getContext());
recyclerView.setAdapter(recipeStepsRecyclerAdapter);
recipeStepsRecyclerAdapter.notifyDataSetChanged();
}
公共类RecipeStepsFragment扩展片段{
@BindView(R.id.recipe\u steps\u rv)
回收视图回收视图;
@BindView(R.id.U电视)
TextView电视节目;
列出步骤;
公共配方步骤片段(){}
@可空
@凌驾
创建视图时的公共视图(@NonNull LayoutInflater inflater、@Nullable ViewGroup container、@Nullable Bundle savedInstanceState){
返回充气机。充气(R.layout.fragment\u recipe\u步骤,容器,错误);
}
@凌驾
已创建公用void onview(@NonNull视图,@Nullable Bundle savedInstanceState){
super.onViewCreated(视图,savedInstanceState);
ButterKnife.bind(这个,视图);
列出成分;
配方=getArguments().getParcelable(“配方”);
步骤=recipe.getSteps();
initRecyclerView();
配料=配方。获取配料();
字符串ingredientsappend=“配料”+“\n\n”;
如果(成分==null){
ingredientsappend=“不可用”;
}否则{
对于(int a=0;a
}
这是我的适配器
public class RecipeStepsRecyclerAdapter extends RecyclerView.Adapter<RecipeStepsRecyclerAdapter.ViewHolder> {
private List<Step> stepList;
private LayoutInflater mInflater;
final private ClickListener clickListener;
public RecipeStepsRecyclerAdapter(List<Step> stepList, ClickListener clickListener, Context context){
this.stepList = stepList;
this.clickListener = clickListener;
mInflater = LayoutInflater.from(context);
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recipe_steps_recyclerview_adapter, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Step step = stepList.get(position);
String stepContent = step.getShortDescription();
holder.listingNumber.setText(String.valueOf(position+1));
holder.stepContent.setText(stepContent);
}
@Override
public int getItemCount() {
return stepList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView listingNumber;
TextView stepContent;
private ViewHolder(View itemView) {
super(itemView);
listingNumber = itemView.findViewById(R.id.list_number_tv);
stepContent = itemView.findViewById(R.id.step_content_tv);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
int clickedPosition = getAdapterPosition();
clickListener.onItemClick(clickedPosition);
}
}
public interface ClickListener{
void onItemClick(int clickedItemPosition);
}
公共类RecipeStepsRecyclerAdapter扩展了RecyclerView.Adapter{
私有列表步骤列表;
私人停车场;
最终私有ClickListener ClickListener;
公共配方步骤循环适配器(列出步骤列表、单击侦听器、单击侦听器、上下文){
this.stepList=步骤列表;
this.clickListener=clickListener;
mInflater=LayoutInflater.from(上下文);
}
@非空
@凌驾
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType){
视图=最小充气器。充气(R.layout.recipe\u steps\u recyclerview\u adapter,parent,false);
返回新的ViewHolder(视图);
}
@凌驾
public void onBindViewHolder(@NonNull ViewHolder,int位置){
步骤=步骤列表。获取(位置);
字符串stepContent=step.getShortDescription();
holder.listingNumber.setText(String.valueOf(position+1));
holder.stepContent.setText(stepContent);
}
@凌驾
public int getItemCount(){
返回stepList.size();
}
公共类ViewHolder扩展了RecyclerView.ViewHolder实现了View.OnClickListener{
文本视图列表编号;
文本视图内容;
私有视图持有者(视图项视图){
超级(项目视图);
listingNumber=itemView.findviewbyd(R.id.list\u number\u tv);
stepContent=itemView.findViewById(R.id.step\u content\u tv);
setOnClickListener(这个);
}
@凌驾
公共void onClick(视图){
int clickedPosition=getAdapterPosition();
clickListener.onItemClick(clickedPosition);
}
}
公共界面ClickListener{
void onItemClick(int clickedItemPosition);
}
}
布局文件如我上面已经解释过的。我想没有什么特别的东西可以在这里发布
提前感谢。每次更改屏幕旋转时,您的活动都会被销毁并重新创建。这就是为什么每次在方向之间切换时,您的列表都会填充新项目的原因 因此,重要的是,您只需实例化一次对象,而不是在每次重新创建应用程序时继续重新创建它们。然后将它们添加到您的列表中 您可以使用和
如果您希望您的应用程序允许方向更改,请应用逻辑,以便您的列表不会在每次创建活动时都获得新项目 问题在于,每次创建
活动时,您都会向该活动添加一个新的片段。以下是您的onCreate(…)
的结尾:
FragmentManager
保留对添加到其中的片段的引用,即使主机活动
已销毁。因此,您不断添加recipes-tepsfragment
的新实例,最终彼此重叠并产生可见的行为
别担心,解决办法是p
RecipeStepsFragment recipeStepsFragment = new RecipeStepsFragment();
recipeStepsFragment.setArguments(b);
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().add(R.id.frame_layout_steps, recipeStepsFragment).commit();
fm.beginTransaction().replace(R.id.frame_layout_steps, recipeStepsFragment).commit();
<activity android:name=".VideoActivity" android:configChanges="keyboardHidden|orientation|screenSize"/>