简体   繁体   English

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

[英]Update RecyclerView with new data in MasterDetail Flow

I'm doing a Mobile App for Tablets and I have added a Master/Detail Flow using the Android Studio steps. 我正在为平板电脑开发移动应用程序,并使用Android Studio步骤添加了主/详细流程。 I have a group of 4 buttons above the Master Detail to select a "Product" and then, when you clic one of them, the RecyclerView is updated with data. 我在“主要详细信息”上方有一组4个按钮,用于选择“产品”,然后,当您选择其中的一个时,RecyclerView会更新数据。

My problem is that if you clic one button (a product), then another, and another, etc.. All data is loaded together so, I need to figure out how to update/refresh the RecyclerView. 我的问题是,如果您按一个按钮(一个产品),然后按另一个按钮,等等,等等。所有数据都一起加载,因此,我需要弄清楚如何更新/刷新RecyclerView。

在此处输入图片说明

In my RecyclerViewAdapter I have added a method to clear, update the ITEMS and then, notifyDataSetChanged. 在我的RecyclerViewAdapter中,我添加了一种方法来清除,更新ITEMS,然后进行notifyDataSetChanged。 This is working good for the rest of the buttons but, not for the first button which is clicked by default programatically. 这对于其余按钮很有用,但不适用于默认情况下以编程方式单击的第一个按钮。 The first button set up the RecyclerView again. 第一个按钮再次设置RecyclerView。

在此处输入图片说明

ProductListActivity 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 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);
        }
    }

}

My goal is to update/refresh the RecyclerView properly every time you click a new button (Product). 我的目标是每次您单击新按钮(产品)时正确更新/刷新RecyclerView。

Everything looks good. 一切看起来都很好。 Just make the following changes: 只需进行以下更改:

  1. You are already setting the recyclerView with null data at: 您已经在以下位置设置了带有空数据的recyclerView:

    setupRecyclerView((RecyclerView) recyclerView, null); setupRecyclerView(((RecyclerView)recyclerView,null);

So, you don't need to set it again in your first button. 因此,您无需在第一个按钮中再次进行设置。

  1. In your Adapter, add the following change in the method getItemCount() 在您的适配器中,在方法getItemCount()中添加以下更改

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

    return mValues.size(); 返回mValues.size(); } }

With this code, you are telling the adapter that at the beginning, when mValues will be null, there will be no data to be displayed. 使用此代码,您告诉适配器在开始时,当mValues为null时,将没有要显示的数据。 Therefore the item count is set to 0. 因此,项目计数设置为0。

Update 更新

  1. Don't programmatically click the first button only to show some data when the app opens. 打开应用程序时,不要以编程方式单击第一个按钮,仅显示一些数据。 Though nothing is wrong, it is not a good coding practice. 尽管没有错,但这不是一个好的编码实践。

Inside onCreate(), call your setupRecyclerView() to get display the data of the first button. 在onCreate()中,调用setupRecyclerView()以显示第一个按钮的数据。

Here is the change : 这是更改:

ProductListActivity 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 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);
        }
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM