Добавление представления к RecyclerView при вызове слушателя - PullRequest
0 голосов
/ 04 августа 2020

Я создал RecyclerView с тремя столбцами sNo, product и price. Первый столбец - это TextView, а следующие два определены как EditText.

Значение sNo сохраняет позицию текущего автоматически сгенерированного представления и значения product и * 1010. * заполняются пользователем. Ниже приведен исходный вид:

enter image description here

I want to append a new View to the list if and only if:

  1. Both the EditText have some value in them.

    And

  2. When an Enter key is hit in any of the EditText

For example after populating first View I want to append a new View like this:

введите описание изображения здесь

Мой код на данный момент:

Адаптер:

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

    private List<OrderListModel> orderList;

    public NewOrderListAdapter(List<OrderListModel> list){ orderList = list; }

    @NonNull
    @Override
    public OrderListAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, 
                                                          int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view = inflater.inflate(R.layout.order_list, parent, false);
        return new ViewHolder(view);
    }
    
    private void addListener(EditText col){
        col.setOnKeyListener(new View.OnKeyListener() {
             @Override
             public boolean onKey(View v, int keyCode, KeyEvent event) {
                 // how to append new item to recyclerview here
             }
        });
    }

    @Override
    public void onBindViewHolder(@NonNull OrderListAdapter.ViewHolder holder,
                                 int position) {
        String sNo = orderList.get(position).getsNo();
        String product = orderList.get(position).getProduct();            
        String price = orderList.get(position).getPrice();
        holder.sNo.setText(sNo);
        holder.product.setText(product);
        addListener(holder.product);
        holder.price.setText(price);
        addListener(holder.price); 
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder {
        EditText product, price;
        TextView sNo;
        public ViewHolder(View itemView){
            super(itemView);
            sNo = (TextView) itemView.findViewById(R.id.sno);
            product = (EditText) itemView.findViewById(R.id.product);
            price = (EditText) itemView.findViewById(R.id.price);
        }
    }
}

MainActivity:

public class MainActivity extends AppCompatActivity {
    
    
    private ArrayList<OrderListModel> orderList;
    private RecycleView orderView;
    private OrderListAdapter orderAdapter;

    private void setupList(){
         orderView = (RecyclerView) findViewById(R.id.content);
         orderView.setLayoutManager(new LinearLayoutManager(this));
         orderList = new ArrayList<>();
         orderAdapter = new OrderListAdapter(orderList);
         orderView.setAdapter(orderAdapter);
    }
    
    private void insertView(String productVal, String priceVal){
         String serialNoVal = String.valueOf(orderAdapter.getItemCount() + 1);
         OrderListModel item = new OrderListModel(serialNoVal, productVal, priceVal);
         orderList.add(item);
    }          

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setupList();
        insertView("", "");
    }          
}

Как добавить новое представление в мой RecyclerView при вызове слушателя onKey?

Изменить:

Я изменил метод addListener() следующим образом:

private void addListener(EditText col) {
   col.setOnKeyListener(new View.OnKeyListener() {
      @Override
      public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN && 
            keyCode == KeyEvent.KEYCODE_ENTER &&
            noEmptyEditText())
               insertView("","");
        return false;
      }
   });
}

Теперь есть две проблемы: как мне определить noEmptyEditText() внутри адаптера? и как мне вызвать insertView("","") внутри onKey слушателя?

Edit 2:

Обновил адаптер, добавив интерфейс:

Адаптер:

public class OrderListAdapter extends RecyclerView.Adapter<OrderListAdapter.ViewHolder>{
    
     //reset of the code
     private final OnEditTextKeyListener listener;

     public interface OnEditTextKeyListener {
         void onEditTextKey(NewOrderListModel list);
     }
    
     public NewOrderListAdapter(List<OrderListModel> list,
                                OnEditTextKeyListener listener) { 
          orderList = list;
          this.listener = listener; 
     }
    
     // reset of the code and removed `addListener`                       
    
     @Override
     public void onBindViewHolder(@NonNull OrderListAdapter.ViewHolder holder,
                                     int position) {
            // reset of the code 
            holder.bind(orderList.get(position), listener);
     }
    
     // reset of the code
    
     public class ViewHolder extends RecyclerView.ViewHolder {
          // reset of the code
          private void addListener(EditText product, final NewOrderListModel list, 
                                    final OnEditTextKeyListener listener){
              product.setOnKeyListener(new View.OnKeyListener() {
                   @Override
                   public boolean onKey(View v, int keyCode, KeyEvent event) {
                       listener.onEditTextKey(list);
                       return false;
                   }
              });
          }

          public void bind(final NewOrderListModel list, 
                         final OnEditTextKeyListener listener) {
               addListener(product, list, listener);
          }
     }
}

MainActivity:

    orderAdapter = new OrderListAdapter(orderList, new OrderListAdapter.OnEditTextKeyListener() {
        @Override
        public void onEditTextKey(OrderListModel list) {
            insertView("","");
        }
    });

С этим обновленным кодом Теперь я могу легко добавить новый элемент, но они добавляются при нажатии любой клавиши, как уменьшить его, чтобы просто ввести клавишу?

Ответы [ 2 ]

0 голосов
/ 05 августа 2020

Наконец создал решение (не стесняйтесь его изменять):

Все, что я сделал, - это создать интерфейс, с помощью которого я мог бы взаимодействовать с активностью из адаптера.

Адаптер:

public class OrderListAdapter extends RecyclerView.Adapter<OrderListAdapter.ViewHolder>{
    
     private List<OrderListModel> orderList;
     private final OnEditTextKeyListener listener;

     public interface OnEditTextKeyListener {
         void onEditTextKey(boolean enterKey, boolean emptyEditText);
     }
    
     public OrderListAdapter(List<OrderListModel> list,
                                OnEditTextKeyListener listener) { 
          orderList = list;
          this.listener = listener; 
     }
    
     @NonNull
     @Override
     public NewOrderListAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, 
                                                              int viewType) {
         LayoutInflater inflater = LayoutInflater.from(parent.getContext());
         View view = inflater.inflate(R.layout.new_order_list, parent, false);
         return new ViewHolder(view);
     }                       
    
     @Override
     public void onBindViewHolder(@NonNull OrderListAdapter.ViewHolder holder,
                                     int position) {
            String sNo = orderList.get(position).getsNo();
            String product = orderList.get(position).getProduct();
            String price = orderList.get(position).getPrice();                
            holder.sNo.setText(sNo);
            holder.product.setText(product);
            holder.price.setText(price);
            holder.bind(position, listener);
     }
    
     private boolean anyEmptyEditText(){
         for (int idx = 0; idx < orderList.size(); idx++)
             if (orderList.get(idx).getProduct().isEmpty() ||
                 orderList.get(idx).getPrice().isEmpty())                
            return true;                             
         return false;
     }
     
     @Override
     public int getItemCount() { return orderList.size(); }
    
     public class ViewHolder extends RecyclerView.ViewHolder {
          EditText product, price;
          TextView sNo;
          public ViewHolder(View itemView){
              super(itemView);
              sNo = (TextView) itemView.findViewById(R.id.sno);
              product = (EditText) itemView.findViewById(R.id.newProduct);
              price = (EditText) itemView.findViewById(R.id.newPrice);
          }

          private void addListener(final EditText editText, final int pos, 
                                   final OnEditTextKeyListener listener){
             editText.setOnKeyListener(new View.OnKeyListener() {
                 @Override
                 public boolean onKey(View v, int keyCode, KeyEvent event) {
                     boolean enterKey = false, emptyEditText = false;
                     if (event.getAction() == KeyEvent.ACTION_UP && 
                         keyCode == KeyEvent.KEYCODE_ENTER) {
                         enterKey = true;
                         emptyEditText = anyEmptyEditText();
                         if (editText == product)
                            price.requestFocus();
                         else
                            product.requestFocus();
                    }else{
                        NewOrderListModel item = new NewOrderListModel(String.valueOf(pos+1), 
                            product.getText().toString(), 
                            price.getText().toString());
                        orderList.set(pos,item);
                    }

                    listener.onEditTextKey(enterKey, emptyEditText);
                    return false;
                 }
            });
         }

         public void bind(int pos, final OnEditTextKeyListener listener) {
             addListener(product, pos, listener);
             addListener(price, pos, listener);                
         }
    }
}

MainActivity:

public class MainActivity extends AppCompatActivity {
    
    
    private ArrayList<OrderListModel> orderList;
    private RecycleView orderView;
    private OrderListAdapter orderAdapter;    
    
    private void insertView(String productVal, String priceVal){
         String serialNoVal = String.valueOf(orderAdapter.getItemCount() + 1);
         OrderListModel item = new OrderListModel(serialNoVal, productVal, priceVal);
         orderList.add(item);
    }

    private void initAdapter(){
         orderView.setLayoutManager(new LinearLayoutManager(this));
         orderList = new ArrayList<>();
    } 

    private void setAdapter(){
         orderAdapter = new NewOrderListAdapter(newOrderList, 
                        new NewOrderListAdapter.OnEditTextKeyListener() {
               @Override
               public void onEditTextKey(boolean enterKey, boolean emptyEditText) {
                    if (enterKey && !emptyEditText)
                         insertNewRow("","");
               }
         });
         orderView.setAdapter(orderAdapter);
    }         

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        orderView = (RecyclerView) findViewById(R.id.content);
        initAdapter();           
        insertView("", "");
        setupAdapter();
    }          
}
0 голосов
/ 04 августа 2020

Для изменения элемента RecyclerView необходимо вызвать один из методов «уведомления» адаптера. например, adapter.notifyItemChanged(row).

Это вызовет такие методы адаптера, как onCreateViewHolder и onBindViewHolder (для указанной строки), где вы можете обновить содержимое.

Вы для поддержания состояния вашего приложения потребуется объект модели данных, поэтому прослушиватель onKey обновит эту модель данных, а затем вызовет notify (). onCreateViewHolder() и onBindViewHolder() могут затем проверить модель данных и использовать правильный набор представлений.

Аналогичным образом вы можете добавлять или удалять строки в своем RecyclerView, вызывая notifyItemInserted() или notifyItemRemoved() на адаптере, которые работают аналогично обновлению существующей строки.

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