Как обновить вид определенной позиции вида переработчика, который в данный момент не находится в фокусе на экране? - PullRequest
1 голос
/ 13 июня 2019

На самом деле я делаю некоторые изменения видимости для элементов, которые щелкаются в представлении переработчика.Но когда пользователь нажимает на один объект, а затем нажимает на другой объект, тогда предыдущий объект должен прийти в свое исходное состояние.Manager.findViewByPosition (position) работает нормально, если представление находится в фокусе экрана, но я не могу получить представление, если элемент не находится в текущем фокусе.Например: - пользователь нажимает на 1-й (позиция) элемент, затем нажимает на последнюю позицию, затем findViewByPosition возвращает ноль.

Пожалуйста, помогите и дайте мне знать, если есть какой-то другой способ сделать это.

Ожидаемым результатом должно быть представление последнего элемента, который должен быть обновлен, но этого не происходит для представлений, которые не находятся в текущем фокусе экрана.

Ниже приведен мой фрагмент кода.Обновлено с тем, что вы предложили.

public class BodyPartWithMmtRecyclerView extends 
RecyclerView.Adapter<BodyPartWithMmtRecyclerView.ViewHolder>
{
   //variables defined. 
   int selectedPosition = -1;
   static class ViewHolder extends RecyclerView.ViewHolder {
   //All the view items declared here.
   ViewHolder(View view) {
        super(view);
  //All the views are defined here.
  }
} 
public BodyPartWithMmtRecyclerView(List<BodyPartWithMmtSelectionModel> bodyPartsList, Context context){
//array list initialization and shared preference variables initialization
}

public BodyPartWithMmtRecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    //Creating a new view.
}

 public void onBindViewHolder(@NonNull final BodyPartWithMmtRecyclerView.ViewHolder holder, @SuppressLint("RecyclerView") final int position) {
BodyPartWithMmtSelectionModel bodyPartWithMmtSelectionModel = bodyPartsList.get(position);
    holder.iv_bodypart.setImageResource(bodyPartWithMmtSelectionModel.getIv_body_part());
    holder.tv_body_part_name.setText(bodyPartWithMmtSelectionModel.getExercise_name());

if(selectedPosition!=position && selectedPosition!=-1){
 //updated the elements view to default view. Like made the visibility and other changes here.           
    }

 //some click listeners on the sub-elements of the items. Like textviews, spinner, etc
holder.iv_bodypart.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ((BodyPartSelection)context).setFabVisible();
            if(selectedPosition!=-1){
                ((BodyPartSelection)context).visibilityChanged(selectedPosition,position);
           /*here what I was doing is whenever the user clicks on an item I check weather a previous item is clicked or not then if yes then I send the position to a function that makes it to default but the issue was that if the item is not in the focus of the screen the findViewByPosition returns null.*/

            }
            selectedPosition = position;
            bodypartSelected = holder.tv_body_part_name.getText().toString();
            holder.iv_bodypart.setVisibility(View.INVISIBLE);
            holder.rl_left_right.setVisibility(View.VISIBLE);
        }
    });


   //and other listeners below 

}

 @Override
public int getItemCount() {
    return bodyPartsList==null?0:bodyPartsList.size();
}

@Override
public int getItemViewType(int position) {
    return position;
}

}

Функция VisibilityChanged

public void visibilityChanged(int position, int clicked){

          View view = manager.findViewByPosition(position);
          if(view!=null) {
            Log.i("inside","visibility change");
            ImageView imageView = view.findViewById(R.id.bodypartImage);
            //other elements and changing the visibility of elemets to default.
           }
    }

Ответы [ 2 ]

2 голосов
/ 13 июня 2019

Я обновил свой код на основе обновленного вами фрагмента.Пожалуйста, не изменяйте условие видимости, если бы я не добавил другую логику, которую я видел в вашем фрагменте кода.Как и вы, он не будет обновлять как выбранный вид, так и вид по умолчанию, поскольку RecyclerView повторно использует макет представления.Поэтому, если условие не является надлежащим, вы можете увидеть несколько выбранных элементов или некоторые другие типы ненатурального поведения.

    public void onBindViewHolder(@NonNull final BodyPartWithMmtRecyclerView.ViewHolder holder, @SuppressLint("RecyclerView") final int position) {
    BodyPartWithMmtSelectionModel bodyPartWithMmtSelectionModel = bodyPartsList.get(position);
    holder.iv_bodypart.setImageResource(bodyPartWithMmtSelectionModel.getIv_body_part());
    holder.tv_body_part_name.setText(bodyPartWithMmtSelectionModel.getExercise_name());

    if(selectedPosition == position){
        //updated the elements view to SELECTED VIEW. Like made the visibility and other changes here.           
    } else {
        //updated the elements view to default view. Like made the visibility and other changes here.
    }

     //some click listeners on the sub-elements of the items. Like textviews, spinner, etc
    holder.iv_bodypart.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ((BodyPartSelection)context).setFabVisible();


            /Comment by Hari: Don't try to change the visibility of default as it will be done automatically after calling notifyDataSetChanged(). */
            if(selectedPosition!=-1){
                ((BodyPartSelection)context).visibilityChanged(selectedPosition,position);
           /*here what I was doing is whenever the user clicks on an item I check weather a previous item is clicked or not then if yes then I send the position to a function that makes it to default but the issue was that if the item is not in the focus of the screen the findViewByPosition returns null.*/

           /*Comment by Hari: This snippet is valuable which is missing as you are getting null issue here.
           However Don't try to change the visibility of default as it will be done automatically after calling notifyDataSetChanged(). */

            }
            selectedPosition = position;
            bodypartSelected = holder.tv_body_part_name.getText().toString();
            holder.iv_bodypart.setVisibility(View.INVISIBLE);
            holder.rl_left_right.setVisibility(View.VISIBLE);

            //Keep this as last statement in onClick
            notifyDataSetChanged();
        }
    });

   //and other listeners below 

}

Дайте мне знать ваш дальнейший ответ.

0 голосов
/ 13 июня 2019

На основании ответа @Hari N Jha.

Звоните notifyDataSetChanged(), когда вы обновляете что-либо.Например,

    int selectedPosition = -1;

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

        if(position == selectedPosition) {
            //Add background color change of your layout or as you want for selected item.
        } else {
            //Add background color change of your layout or as you want for default item.
        }
        notifyDataSetChanged(); //Call notifyDataSetChanged() here after done all the stufs
        //...
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...