底部弹出窗口中RecyclerView内容更新失败

9

我希望通过点击事件更改底部表视图中的列表内容,但是我只得到了空表。这是从BottomSheetSample(github.com/niravkalola/BottomSheetSample)修改的演示。

mainActivity.java

package com.nkdroid.bottomsheetsample;

import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.BottomSheetDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MainActivity extends AppCompatActivity implements    ItemAdapter.ItemListener {

private Button btnView, btnDialog;
BottomSheetBehavior behavior;
private BottomSheetDialog mBottomSheetDialog;
private ItemAdapter mAdapter;
RecyclerView recyclerView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btnView = (Button) findViewById(R.id.btnView);
    btnDialog = (Button) findViewById(R.id.btnDialog);
    btnView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mAdapter = new ItemAdapter(createItems());
            recyclerView.setAdapter(mAdapter);
            behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
        }
    });

    btnDialog.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            showBottomSheetDialog();
        }
    });

    View bottomSheet = findViewById(R.id.bottom_sheet);
    behavior = BottomSheetBehavior.from(bottomSheet);
    behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) {
            // React to state change
        }

        @Override
        public void onSlide(@NonNull View bottomSheet, float slideOffset) {
            // React to dragging events
        }
    });

    recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));

    mAdapter = new ItemAdapter(createItems(), this);
    recyclerView.setAdapter(mAdapter);

}


private void showBottomSheetDialog() {
    if (behavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
        behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
    }

    mBottomSheetDialog = new BottomSheetDialog(this);
    View view = getLayoutInflater().inflate(R.layout.sheet, null);
    RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setAdapter(new ItemAdapter(createItems(), new ItemAdapter.ItemListener() {
        @Override
        public void onItemClick(Item item) {
            if (mBottomSheetDialog != null) {
                mBottomSheetDialog.dismiss();
            }
        }
    }));

    mBottomSheetDialog.setContentView(view);
    mBottomSheetDialog.show();
    mBottomSheetDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
        @Override
        public void onDismiss(DialogInterface dialog) {
            mBottomSheetDialog = null;
        }
    });
}


@Override
protected void onDestroy() {
    super.onDestroy();
    mAdapter.setListener(null);
}

public List<Item> createItems() {
    Random r = new Random();
    ArrayList<Item> items = new ArrayList<>();
    items.add(new Item(R.mipmap.ic_launcher, "Item 1"+ r.nextInt(100)));
    items.add(new Item(R.mipmap.ic_launcher, "Item 2"));
    items.add(new Item(R.mipmap.ic_launcher, "Item 3"));
    items.add(new Item(R.mipmap.ic_launcher, "Item 4"));
    return items;
}

@Override
public void onItemClick(Item item) {
    behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}

}

ItemAdapter.java:

package com.nkdroid.bottomsheetsample;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;


public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> {

private List<Item> mItems;
private ItemListener mListener;

public ItemAdapter(List<Item> items, ItemListener listener) {
    mItems = items;
    mListener = listener;
}

public ItemAdapter(List<Item> items) {
    mItems = items;
}

public void setListener(ItemListener listener) {
    mListener = listener;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    return new ViewHolder(LayoutInflater.from(parent.getContext())
            .inflate(R.layout.adapter, parent, false));
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.setData(mItems.get(position));
}

@Override
public int getItemCount() {
    return mItems.size();
}

public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    public ImageView imageView;
    public TextView textView;
    public Item item;

    public ViewHolder(View itemView) {
        super(itemView);
        itemView.setOnClickListener(this);
        imageView = (ImageView) itemView.findViewById(R.id.imageView);
        textView = (TextView) itemView.findViewById(R.id.textView);
    }

    public void setData(Item item) {
        this.item = item;
        imageView.setImageResource(item.getDrawableResource());
        textView.setText(item.getTitle());
    }

    @Override
    public void onClick(View v) {
        if (mListener != null) {
            mListener.onItemClick(item);
        }
    }
}

public interface ItemListener {
    void onItemClick(Item item);
}
}

以下是首次和第二次单击“显示视图”按钮后的截图: 首次单击 第二次单击

如果您在手机上按“最近使用的应用”按钮并打开另一个应用程序,然后再次按下该按钮并返回到您的应用程序,那么您的RecyclerView中的项目是否出现? - Blundell
1个回答

9
这个问题在24.0.0版本中得到了修复,即recyclerView已经更新。但是如果您在bottomsheet和recyclerview上都使用了wrap_content,则需要使用此代码以正确计算bottomsheet的高度。
  bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {

                if(newState==BottomSheetBehavior.STATE_EXPANDED){
                    bottomSheet.requestLayout();

                    /*or
                     recyclerView.scrollToPosition(0);
                     recyclerView.requestLayout();*/

                }
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {

            }
        });

如果您想使用早期版本,请使用

 bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {

                if(newState==BottomSheetBehavior.STATE_EXPANDED){
                    bottomSheet.requestLayout();
                    bottomSheet.invalidate();
                }
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {

            }
        });

使用建议的回调函数是有效的。notifyDataSetChanged 现在具有预期的效果。谢谢。 - tom-pratt
bottomSheet.requestLayout(); bottomSheet.invalidate(); 放在回调中真的很有帮助。谢谢! - Alexandr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接