Как отобразить несколько типов элементов в RecyclerView? - PullRequest
0 голосов
/ 15 февраля 2019

Я создаю приложение для Android в Java, я использую базу данных Room.У меня есть три таблицы:

Users table( user_id and user_name) 
Products table( product_id and product_name)
Orders table ( order_id  , user_id  and product_id )

Я использую ViewModel для запроса информации и заполнения ее в пользовательском интерфейсе.

У меня есть один запрос, который из таблицы Orders получает user_id и product_id.У меня такой случай: user_id № 1 заказал 3 товара.

private void setUpViewModel() {

viewModel.getUserProduct(1).observe(this,new Observer<List<OrdersTable>>() {
            @Override
            public void onChanged(@Nullable List<OrdersTable> order) {
                mAdapter.setUserList((ArrayList<OrdersTable>) order);
            }
        }
       );
     }

этот запрос получит продукт 1,2 и 3 для пользователя №1

Я хочу отобразить имя пользователя и название продукта в моем recylcerView, но я не знаюкак отобразить два разных типа таблицы (таблица пользователя и таблица продукта) в recylcerView.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<TextView

    android:id="@+id/tv_userName_xml"
    android:text="user name"
    android:layout_margin="20dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

<TextView
    android:id="@+id/tv_prodcutName_xml"
    android:layout_marginLeft="40dp"
    android:text="product"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />


</LinearLayout>

enter image description here

 public class MyAdapter extends   RecyclerView.Adapter<MyAdapter.MyViewHolder> {
 private Context mContext;
 ArrayList<OrderTable> order_list;
 ArrayList<UserTable> user_list; 
 ArrayList<ProductTable> product_list;

 public MyAdapter(Context context) {
    this.mContext = context;
}

 @NonNull
@Override
public MyAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_ts,  parent, false);
    MyAdapter.MyViewHolder viewHolder = new   MyAdapter.MyViewHolder(view);

    return viewHolder;
}

@Override
public void onBindViewHolder(@NonNull MyAdapter.MyViewHolder holder, int position) {

    OrderTable orders = order_list.get(position);
    UserTable user = user_list.get(position);
    ProductTable productTable = product_list.get(position);

    holder.tv_userName.setText(user.getUserName());

    holder.tv_productName.setText(productTable.getProductName());
}


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


public class MyViewHolder extends RecyclerView.ViewHolder {
    TextView tv_userName, tv_productName;

    public MyViewHolder(View itemView) {
        super(itemView);
        tv_userName= itemView.findViewById(R.id.tv_userName_xml);
        tv_productName= itemView.findViewById(R.id.tv_prodcutName_xml);

    }

}

public void setTs_list(ArrayList<OrderTable> ts) {
    this.order_list = ts;
    notifyDataSetChanged();
}


 }

Ответы [ 3 ]

0 голосов
/ 15 февраля 2019

Мой совет - использовать разные типы представлений. Вот статья об этом

Прежде всего, вам нужно придумать абстракцию источника данных для вашего адаптера.Обычно у нас есть простой массив или список в качестве источника данных, но в вашем случае у вас есть не один, а три типа.Таким образом, вы можете создать интерфейс или использовать коллекцию для хранения всех ваших данных в адаптере, так, как вы хотите, чтобы это было на ваше усмотрение.После этого вам нужно создать разные константы для каждого типа ваших моделей.В вашем примере у вас есть три модели: пользователь, продукт и заказ.Поэтому я бы рекомендовал создать три константы для каждого из этих типов.Эти константы должны быть помещены в ваш класс адаптера как статические поля.

private static final int USER_VIEW_TYPE = 1;
private static final int PRODUCT_VIEW_TYPE = 2;
private static final int ORDER_VIEW_TYPE = 3;

Затем вы должны переопределить метод getItemViewType(int position) в вашем адаптере.Там вы должны указать адаптеру, какой тип имеет конкретный элемент.Например, вы решили сохранить все свои данные как List<Object> (но не делайте этого в производственном коде, я использую тип Object здесь только для примера.).Таким образом, в этом случае ваш метод будет выглядеть следующим образом:

@Override public int getItemViewType(int position) {
    if (data[position] instanceof User) {
        return USER_VIEW_TYPE;
    } else if (data[position] instanceof PRODUCT_VIEW_TYPE) {
        return PRODUCT_VIEW_TYPE;
    } else return ORDER_VIEW_TYPE;
}

После этого вам нужно создать различные ViewHolders для ваших типов, чтобы у вас были UserViewHolder, ProductViewHolder и OrderViewHolder,И, чтобы наконец их дифференцировать, вы должны использовать параметр viewType в методе onCreateViewHolder.Логика довольно проста: вы должны проверить значение этого параметра и раздувать различные макеты в зависимости от результата.Например:

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        if (viewType == USER_VIEW_TYPE) {
            return new UserViewHolder(layoutInflater.inflate(R.layout.item_user_type, parent));
        } else if (viewType == PRODUCT_VIEW_TYPE) {
            return new ProductViewHolder(layoutInflater.inflate(R.layout.item_product_type, parent));
        } else return new OrderViewHolder(layoutInflater.inflate(R.layout.item_order_type, parent));
    }
0 голосов
/ 15 февраля 2019

Вы можете объединить данные из этих таблиц и связать их, что приведет к созданию пользовательского класса модели с именем ResultModel. Вы можете получить user_name и product_name от этого ResultModel

пользователя стол

enter image description here

продукт стол

enter image description here

t_order таблица

enter image description here

Запрос на присоединение:

выберите имя пользователя u, p.product_name от пользователя u, product p, t_order o, где o.user_id = u.user_id и o.product_id = p.product_id

результат

enter image description here

Создать один класс модели ResultModel

public class ResultModel {
  public String getUser_name() {
   return user_name;
  }

  public String getProduct_name() {
   return product_name;
  }

  private String user_name;
  private String product_name;
}

Обновлен наблюдатель

Примечание: заменить OrdersTableс ResultModel везде, где требуется в вашем Adapter тоже

viewModel.getUserProduct(1).observe(this,new Observer<List<ResultModel>>() {
        @Override
        public void onChanged(@Nullable List<ResultModel> order) {
            mAdapter.setUserList((ArrayList<ResultModel>) order);
        }
    }
   );
 }
0 голосов
/ 15 февраля 2019

Вы можете создать несколько видов рециркуляции внутри onBindViewHolder, как это

@Override
    public void onBindViewHolder(ItemRowHolder itemRowHolder, int i) {

        final String sectionName = dataList.get(i).getHeaderTitle();

        ArrayList singleSectionItems = dataList.get(i).getAllItemsInSection();

        itemRowHolder.itemTitle.setText(sectionName);

        SectionListDataAdapter itemListDataAdapter = new SectionListDataAdapter(mContext, singleSectionItems);

        itemRowHolder.recycler_view_list.setHasFixedSize(true);
        itemRowHolder.recycler_view_list.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false));
        itemRowHolder.recycler_view_list.setAdapter(itemListDataAdapter);

    }



public class ItemRowHolder extends RecyclerView.ViewHolder {

        protected TextView itemTitle;

        protected RecyclerView recycler_view_list;




        public ItemRowHolder(View view) {
            super(view);

            this.itemTitle = (TextView) view.findViewById(R.id.itemTitle);
            this.recycler_view_list = (RecyclerView) view.findViewById(R.id.recycler_view_list);


        }

    }

См. Пример кода здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...