Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
每次旋转设备时,Android-RecyclerView都会自我倍增_Android_Android Recyclerview - Fatal编程技术网

每次旋转设备时,Android-RecyclerView都会自我倍增

每次旋转设备时,Android-RecyclerView都会自我倍增,android,android-recyclerview,Android,Android Recyclerview,我有一个应用程序活动的横向配置。此活动包含一个片段,此片段包含一个textview和一个recyclerview。每次我在纵向和横向模式之间切换时,recyclerview都会留下自己的视图,就像我打开设备之前一样。这可能有点难理解我想问什么,所以我录了一张gif 这是我的活动 public class RecipeStepsActivity extends AppCompatActivity { static Recipe recipe; @Override protected void

我有一个应用程序活动的横向配置。此活动包含一个片段,此片段包含一个textview和一个recyclerview。每次我在纵向和横向模式之间切换时,recyclerview都会留下自己的视图,就像我打开设备之前一样。这可能有点难理解我想问什么,所以我录了一张gif

这是我的活动

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"/>