在MasterDetail Flow中使用新数据更新RecyclerView

时间:2019-05-19 17:00:24

标签: android android-recyclerview master-detail

我正在为平板电脑开发移动应用程序,并使用Android Studio步骤添加了主/详细流程。我在“主要详细信息”上方有一组4个按钮,可以选择一个“产品”,然后,当您选择其中的一个时,RecyclerView就会更新数据。

我的问题是,如果您按一个按钮(一个产品),然后按另一个按钮,等等,等等。所有数据都一起加载,因此,我需要弄清楚如何更新/刷新RecyclerView。

enter image description here

在我的RecyclerViewAdapter中,我添加了一种方法来清除,更新ITEMS,然后notifyDataSetChanged。这对于其余按钮很有用,但不适用于默认情况下以编程方式单击的第一个按钮。第一个按钮再次设置RecyclerView。

enter image description here

ProductListActivity

public class ProductListActivity extends AppCompatActivity implements View.OnClickListener {

    /**
     * Whether or not the activity is in two-pane mode, i.e. running on a tablet
     * device.
     */
    private boolean mTwoPane;

    // Group of buttons
    private Button[] btn = new Button[4];
    private Button btn_unfocus;
    private int[] btn_id = {R.id.btn0, R.id.btn1, R.id.btn2, R.id.btn3};

    private View recyclerView;
    private ItemRecyclerViewAdapter mAdapter;
    private MyDatabase mMyDatabase;

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

        if (findViewById(R.id.product_detail_container) != null) {
            // The detail container view will be present only in the
            // large-screen layouts (res/values-w900dp).
            // If this view is present, then the
            // activity should be in two-pane mode.
            mTwoPane = true;
        }

        mMyDatabase = Utils.getDatabase(ProductListActivity.this);

        recyclerView = findViewById(R.id.product_list);
        assert recyclerView != null;

        // Initialize the button group
        initButtonGroup();
    }

    private void initButtonGroup() {
        for(int i = 0; i < btn.length; i++){
            btn[i] = (Button) findViewById(btn_id[i]);
            btn[i].setBackgroundColor(ContextCompat.getColor(this, R.color.customGreenDark));
            btn[i].setTextColor(Color.WHITE);
            btn[i].setOnClickListener(this);
        }

        btn_unfocus = btn[0];

        // Set the first button clicked by default
        btn[0].performClick();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn0 :
                setFocus(btn_unfocus, btn[0]);
                List<Presentation.IdAndPresentationTuple> presentationList1 = mMyDatabase.presentationDao()
                        .getProductRepresentationsByName("Product 1");
                // Set up for the first time
                setupRecyclerView((RecyclerView) recyclerView, presentationList1);
                mAdapter.updateData(presentationList1);
                break;

            case R.id.btn1:
                setFocus(btn_unfocus, btn[1]);
                List<Presentation.IdAndPresentationTuple> presentationList2 = mMyDatabase.presentationDao()
                        .getProductRepresentationsByName("Product 2");
                // Update data
                mAdapter.updateData(presentationList2);
                break;

            case R.id.btn2:
                setFocus(btn_unfocus, btn[2]);
                List<Presentation.IdAndPresentationTuple> presentationList3 = mMyDatabase.presentationDao()
                        .getProductRepresentationsByName("Product 3");
                // Update data
                mAdapter.updateData(presentationList3);
                break;
        }
    }

    private void setFocus(Button btn_unfocus, Button btn_focus){
        btn_unfocus.setTextColor(Color.WHITE);
        btn_unfocus.setTypeface(null, Typeface.NORMAL);
        btn_unfocus.setBackgroundColor(ContextCompat.getColor(this, R.color.customGreenDark));
        btn_focus.setTextColor(Color.BLACK);
        btn_focus.setTypeface(null, Typeface.BOLD);
        btn_focus.setBackground(getDrawable(R.drawable.button_border_yellow));
        this.btn_unfocus = btn_focus;
    }

    private void setupRecyclerView(@NonNull RecyclerView recyclerView, List<Presentation.IdAndPresentationTuple> ITEMS) {
        mAdapter = new ItemRecyclerViewAdapter(this, ITEMS, mTwoPane);
        recyclerView.setHasFixedSize(true);
        recyclerView.setAdapter(mAdapter);
        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
    }
}

ItemRecyclerViewAdapter

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

    private final ProductListActivity mParentActivity;
    private final List<Presentation.IdAndPresentationTuple> mValues;
    private final boolean mTwoPane;

    ItemRecyclerViewAdapter(ProductListActivity parent,
                            List<Presentation.IdAndPresentationTuple> items,
                            boolean twoPane) {
        mParentActivity = parent;
        mValues = items;
        mTwoPane = twoPane;
    }

    // My custom method to clear, update and notifyDataSetChanged
    public void updateData(List<Presentation.IdAndPresentationTuple> items) {
        mValues.clear();
        mValues.addAll(items);
        notifyDataSetChanged();
    }

    private final View.OnClickListener mOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Presentation.IdAndPresentationTuple item = (Presentation.IdAndPresentationTuple) view.getTag();
            if (mTwoPane) {
                Bundle arguments = new Bundle();
                // Send the id of the product to show
                arguments.putString(ProductDetailFragment.ARG_ITEM_ID, String.valueOf(item.getId()));
                ProductDetailFragment fragment = new ProductDetailFragment();
                fragment.setArguments(arguments);
                mParentActivity.getSupportFragmentManager().beginTransaction()
                        .replace(R.id.product_detail_container, fragment)
                        .commit();
            } else {
                Context context = view.getContext();
                Intent intent = new Intent(context, ProductDetailActivity.class);
                intent.putExtra(ProductDetailFragment.ARG_ITEM_ID, String.valueOf(item.getId()));

                context.startActivity(intent);
            }
        }
    };

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

    @Override
    public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
        holder.mIdView.setText(String.valueOf(mValues.get(position).getId()));
        holder.mRepresentationNameView.setText(mValues.get(position).getPresentationName());

        holder.itemView.setTag(mValues.get(position));
        holder.itemView.setOnClickListener(mOnClickListener);
    }

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

    class ViewHolder extends RecyclerView.ViewHolder {
        final TextView mIdView;
        final TextView mRepresentationNameView;

        ViewHolder(View view) {
            super(view);
            mIdView = (TextView) view.findViewById(R.id.id);
            mRepresentationNameView = (TextView) view.findViewById(R.id.representationName);
        }
    }

}

我的目标是每次单击新按钮(产品)时正确更新/刷新RecyclerView。

1 个答案:

答案 0 :(得分:0)

一切看起来不错。只需进行以下更改:

  1. 您已经在以下位置设置了带有空数据的recyclerView:

    setupRecyclerView(((RecyclerView)recyclerView,null);

因此,您无需在第一个按钮中再次进行设置。

  1. 在适配器中,在方法getItemCount()中添加以下更改

    @Override         public int getItemCount(){ if(mValues == null) 返回0;

    返回mValues.size();         }

使用此代码,您告诉适配器在开始时,当mValues为null时,将不会显示任何数据。因此,项目计数设置为0。

更新

  1. 在打开应用程序时,不要以编程方式单击第一个按钮只是显示一些数据。尽管没什么错,但这不是一个好的编码实践。

在onCreate()中,调用setupRecyclerView()以显示第一个按钮的数据。

这是零钱:

ProductListActivity

public class ProductListActivity extends AppCompatActivity implements View.OnClickListener {

    /**
     * Whether or not the activity is in two-pane mode, i.e. running on a tablet
     * device.
     */
    private boolean mTwoPane;

    // Group of buttons
    private Button[] btn = new Button[4];
    private Button btn_unfocus;
    private int[] btn_id = {R.id.btn0, R.id.btn1, R.id.btn2, R.id.btn3};

    private View recyclerView;
    private ItemRecyclerViewAdapter mAdapter;
    private MyDatabase mMyDatabase;

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

        if (findViewById(R.id.product_detail_container) != null) {
            // The detail container view will be present only in the
            // large-screen layouts (res/values-w900dp).
            // If this view is present, then the
            // activity should be in two-pane mode.
            mTwoPane = true;
        }

        mMyDatabase = Utils.getDatabase(ProductListActivity.this);

        recyclerView = findViewById(R.id.product_list);

       //Get the data that you want to display for the first time
        List<Presentation.IdAndPresentationTuple> presentationList1 = mMyDatabase.presentationDao()
                        .getProductRepresentationsByName("Product 1");


                // Set up recycler view for the first time

               setupRecyclerView((RecyclerView) recyclerView, presentationList1);

                mAdapter.updateData(presentationList1); //Call the update method

        // Initialize the button group
        initButtonGroup();
    }

    private void initButtonGroup() {
        for(int i = 0; i < btn.length; i++){
            btn[i] = (Button) findViewById(btn_id[i]);
            btn[i].setBackgroundColor(ContextCompat.getColor(this, R.color.customGreenDark));
            btn[i].setTextColor(Color.WHITE);
            btn[i].setOnClickListener(this);
        }

        btn_unfocus = btn[0];

        // Set the first button clicked by default
        //btn[0].performClick(); //Don't perform manual click
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn0 :
                setFocus(btn_unfocus, btn[0]);
                List<Presentation.IdAndPresentationTuple> presentationList1 = mMyDatabase.presentationDao()
                        .getProductRepresentationsByName("Product 1");

                mAdapter.updateData(presentationList1);
                break;

            case R.id.btn1:
                setFocus(btn_unfocus, btn[1]);
                List<Presentation.IdAndPresentationTuple> presentationList2 = mMyDatabase.presentationDao()
                        .getProductRepresentationsByName("Product 2");
                // Update data
                mAdapter.updateData(presentationList2);
                break;

            case R.id.btn2:
                setFocus(btn_unfocus, btn[2]);
                List<Presentation.IdAndPresentationTuple> presentationList3 = mMyDatabase.presentationDao()
                        .getProductRepresentationsByName("Product 3");
                // Update data
                mAdapter.updateData(presentationList3);
                break;
        }
    }

    private void setFocus(Button btn_unfocus, Button btn_focus){
        btn_unfocus.setTextColor(Color.WHITE);
        btn_unfocus.setTypeface(null, Typeface.NORMAL);
        btn_unfocus.setBackgroundColor(ContextCompat.getColor(this, R.color.customGreenDark));
        btn_focus.setTextColor(Color.BLACK);
        btn_focus.setTypeface(null, Typeface.BOLD);
        btn_focus.setBackground(getDrawable(R.drawable.button_border_yellow));
        this.btn_unfocus = btn_focus;
    }

    private void setupRecyclerView(@NonNull RecyclerView recyclerView, List<Presentation.IdAndPresentationTuple> ITEMS) 
    {


        if(recyclerView.getAdapter()==null)
        {
            //Set the Adapter for the first time only 
             mAdapter = new ItemRecyclerViewAdapter(this, null, mTwoPane);
              recyclerView.setHasFixedSize(true);
              recyclerView.setAdapter(mAdapter);
              recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        }

    }
}

ItemRecyclerViewAdapter

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

    private final ProductListActivity mParentActivity;
    private final List<Presentation.IdAndPresentationTuple> mValues;
    private final boolean mTwoPane;

    ItemRecyclerViewAdapter(ProductListActivity parent,
                            List<Presentation.IdAndPresentationTuple> items,
                            boolean twoPane) {
        mParentActivity = parent;
        mValues = items;
        mTwoPane = twoPane;
    }

    // My custom method to clear, update and notifyDataSetChanged
    public void updateData(List<Presentation.IdAndPresentationTuple> items) 
    {
        if(items!=null)
        {
             mValues.clear();
            mValues.addAll(items);
            notifyDataSetChanged();
        }

    }

    private final View.OnClickListener mOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Presentation.IdAndPresentationTuple item = (Presentation.IdAndPresentationTuple) view.getTag();
            if (mTwoPane) {
                Bundle arguments = new Bundle();
                // Send the id of the product to show
                arguments.putString(ProductDetailFragment.ARG_ITEM_ID, String.valueOf(item.getId()));
                ProductDetailFragment fragment = new ProductDetailFragment();
                fragment.setArguments(arguments);
                mParentActivity.getSupportFragmentManager().beginTransaction()
                        .replace(R.id.product_detail_container, fragment)
                        .commit();
            } else {
                Context context = view.getContext();
                Intent intent = new Intent(context, ProductDetailActivity.class);
                intent.putExtra(ProductDetailFragment.ARG_ITEM_ID, String.valueOf(item.getId()));

                context.startActivity(intent);
            }
        }
    };

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

    @Override
    public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
        holder.mIdView.setText(String.valueOf(mValues.get(position).getId()));
        holder.mRepresentationNameView.setText(mValues.get(position).getPresentationName());

        holder.itemView.setTag(mValues.get(position));
        holder.itemView.setOnClickListener(mOnClickListener);
    }

    @Override
    public int getItemCount() 
    {
        if(mValues==null)
        {
            return 0;
        }
        return mValues.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder {
        final TextView mIdView;
        final TextView mRepresentationNameView;

        ViewHolder(View view) {
            super(view);
            mIdView = (TextView) view.findViewById(R.id.id);
            mRepresentationNameView = (TextView) view.findViewById(R.id.representationName);
        }
    }

}