0

J'ai un RecyclerView qui affiche des images avec des cases à cocher. Lorsqu'une case est cochée, les éléments associés à l'image sont enregistrés dans une base de données. J'ai aussi un index de l'alphabet qui, lorsqu'il est cliqué, appelle une fonction qui filtre les images et met à jour la vue recycleur pour afficher les images dont le titre correspond à la lettre de l'alphabet cliquée. Le problème est que les images RecyclerView ne sont mises à jour qu'au premier clic. Il n'y a pas de mise à jour des images RecyclerView avec les clics suivants. J'ai vérifié et il apparaît que la fonction est appelée avec les clics suivants que je suis capable d'afficher des messages Toast à travers divers points de la fonction. Seule RecyclerView ne met pas à jour les données d'images filtrées et je n'ai aucune idée de la raison pour laquelle il n'est pas mis à jour. Toute aide à ce sujet serait appréciée.OnClick Listener met à jour la vue recycleur uniquement au premier clic.

Voici l'activité principale:

public class AddBrandPage extends AppCompatActivity implements OnClickListener { 

    //declare variables 
    private RecyclerView recyclerView; 
    private RecyclerView.LayoutManager layoutManager; 
    private RecyclerView.Adapter adapter; 
    private RecyclerView alpharecyclerView; 
    private RecyclerView.LayoutManager alphaLayoutManager; 
    private RecyclerView.Adapter alphaAdapter; 
    private DatabaseReference myRef; 
    private DatabaseReference userRef; 
    private Button btn_skip; 
    private Button btn_save; 
    private CheckBox checkbox; 
    private String t; 
    private String letter; 
    List<LogoItems> brandLogo = new ArrayList<>(); 
    //HashMap<String, String> saveBrands = new HashMap<>(); 
    List<LogoItems> removedBrandLogo = new ArrayList<>(); 
    List<String> selectionList = new ArrayList<>(); 
    List<AlphaItems> alphaList = new LinkedList<>(); 
    List<LogoItems> tmp = new ArrayList<>(); 



    String[] alphabets = {"All", "A", "B", "C", "D", "E", "F", "G", "H", "I", 
      "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; 


    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_add_brand_page); 

     //initialize variables 
     btn_skip = (Button) findViewById(R.id.btn_skip); 
     btn_save = (Button) findViewById(R.id.btn_save); 
     myRef = FirebaseDatabase.getInstance().getReference().child("/brands"); 
     userRef = FirebaseDatabase.getInstance().getReference().child("/users"); 


     //calls to load data to arraylists 
     loadAlpha(); 
     loadLogoImgData(); 


     //set the listener for the buttons click event 
     btn_skip.setOnClickListener(this); 
     btn_save.setOnClickListener(this); 

    } 

    private void loadAlpha() { 

     for (String alpha : alphabets) { 
      alphaList.add(new AlphaItems(alpha)); 

     } 
     startAlphaRecyclerView(); 

    } 

    public void loadLogoImgData() { 

     brandLogo.clear(); 
     myRef.addValueEventListener(new ValueEventListener() { 

      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 

       for (DataSnapshot brandSnapshot : dataSnapshot.getChildren()) { 
        LogoItems value = brandSnapshot.getValue(LogoItems.class); 
        brandLogo.add(value); 
        tmp.add(value); 
       } 
       startLogoRecyclerView(); 
      } 


      @Override 
      public void onCancelled(DatabaseError databaseError) { 

      } 
     }); 

    } 


    @Override 
    public void onClick(View view) { 

     if (view == btn_skip) { 
      //if skip button clicked close current window and go to user main page 
      finish(); 
      startActivity(new Intent(getApplicationContext(), UserMainPage.class)); 

     } 
     if (view == btn_save) { 
      saveData(); 
     } 

    } 


    public void startLogoRecyclerView() { 
     // set the main recyclerview view for the logo in the layout 
     recyclerView = (RecyclerView) findViewById(R.id.recylView); 
     recyclerView.setHasFixedSize(true); 

     // set the main layoutManager of the logo recyclerview 
     layoutManager = new GridLayoutManager(this, 2); 
     recyclerView.setLayoutManager(layoutManager); 

     // set the logo recycler view adapter 
     adapter = new LogoAdapter(brandLogo, getBaseContext(), AddBrandPage.this); 
     recyclerView.setAdapter(adapter); 

    } 

    public void startAlphaRecyclerView() { 
     // set the main recyclerview view for the logo in the layout 
     alpharecyclerView = (RecyclerView) findViewById(R.id.alpharecyclerView); 
     alpharecyclerView.setHasFixedSize(true); 

     // set the main layoutManager of the alpha recyclerview 
     alphaLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false); 
     alpharecyclerView.setLayoutManager(alphaLayoutManager); 

     // set the alpha recycler view adapter 
     alphaAdapter = new AlphaAdapter(alphaList, getBaseContext(), AddBrandPage.this); 
     alpharecyclerView.setAdapter(alphaAdapter); 

    } 


    public List<String> prepareSelection(View v, int position) { 

     checkbox = (CheckBox) v; 

     //check if user selected checkbox and add or remove from list 
     //if (checkbox.isChecked()) { 
     selectionList.add(brandLogo.get(position).getName()); 

     //} else { 
     // selectionList.remove(brandLogo.get(position).getLogo()); 

     //} 
     return selectionList; 
    } 


    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (!(o instanceof AddBrandPage)) return false; 
     AddBrandPage that = (AddBrandPage) o; 

     if (t != null ? !t.equals(that.t) : that.t != null) return false; 
     return letter != null ? letter.equals(that.letter) : that.letter == null; 

    } 

    @Override 
    public int hashCode() { 
     int result = t != null ? t.hashCode() : 0; 
     result = 31 * result + (letter != null ? letter.hashCode() : 0); 
     return result; 
    } 

    public void updateLogoDisplay(final String letter) { 
     int i = 0; 
     brandLogo.clear(); 
     brandLogo.addAll(tmp); 

     if (!(letter.equals("All"))) { 
      //Iterator<LogoItems> iter = brandLogo.iterator(); 

      for (i=0; i< tmp.size(); i++){ //Iterator<LogoItems> iter = tmp.iterator(); iter.hasNext();) { 
       //while (iter.hasNext()) { 
       LogoItems r = tmp.get(i); 
       final String c = r.getName(); 
       if (c != null) { 
        String t = c.substring(0, 1); 
        if (t != null) { 
         if (c != null) { 

          if ((letter.equals(t))) { 
           //brandLogo.remove(r); 
           removedBrandLogo.add(r); 
           //iter.remove(); 

          } 
         } 
        } 
       } else { 
       } 
      } 
      brandLogo.clear(); 
      brandLogo.addAll(removedBrandLogo); 

      adapter.notifyDataSetChanged(); 
      //startLogoRecyclerView(); 
      } 

    } 



    public void saveData() { 

     final FirebaseAuth mAuth; 
     final DatabaseReference userRef; 

     mAuth = FirebaseAuth.getInstance(); 
     userRef = FirebaseDatabase.getInstance().getReference().child("users"); 
     DatabaseReference curUser = userRef.child(mAuth.getCurrentUser().getUid()); 
     curUser.child("brands").setValue(selectionList);//save selected items to the database 

    } 

} 

Voici l'adaptateur alphabet (AlphaAdapter.java):

public class AlphaAdapter extends RecyclerView.Adapter<AlphaAdapter.AlphaViewHolder> { 

    //declare variables 
    List<AlphaItems> alphaList = new ArrayList<>(); 
    private AddBrandPage addBrandPage; 
    private Context context; 



    //the constructor 
    public AlphaAdapter (List<AlphaItems> alphaList, Context context, AddBrandPage addBrandPage){ 
     this.alphaList = alphaList; 
     this.context = context; 
     this.addBrandPage = addBrandPage; 

    } 


    @Override 
    public AlphaAdapter.AlphaViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.alpha_items, parent, false); 
     AlphaViewHolder alphaViewHolder = new AlphaViewHolder(view,addBrandPage); 
     return alphaViewHolder; 
    } 

    @Override 
    public void onBindViewHolder(AlphaAdapter.AlphaViewHolder holder, int position) { 
     holder.txt_alpha.setText(alphaList.get(position).getLetter()); 

    } 

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

    public class AlphaViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ 

     //declare variables 
     private TextView txt_alpha; 
     private AddBrandPage addBrandPage; 


     //the constructor 
     public AlphaViewHolder (View itemView, AddBrandPage addBrandPage){ 
      super(itemView); 
      this.addBrandPage = addBrandPage; 



      //initialize variables 
      txt_alpha = (TextView) itemView.findViewById(R.id.txt_alpha); 

      //set click listener 
      txt_alpha.setOnClickListener(this); 


     } 



     @Override 
     public void onClick(View v) { 
      int position = getAdapterPosition(); 
      String letter = alphaList.get(position).getLetter(); 
      addBrandPage.updateLogoDisplay(letter); 

     } 
    } 

} 

Voici la mise en page d'index de l'alphabet (de alpha_items.xml):

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

    <android.support.v7.widget.CardView 
     android:layout_width="40dp" 
     android:layout_height="40dp" 
     android:scrollbars="horizontal" 
     > 

     <TextView 
      android:id="@+id/txt_alpha" 
      android:layout_width="40dp" 
      android:layout_height="40dp" 
      android:layout_gravity="center_vertical" 
      android:layout_marginLeft="15dp" 
      android:layout_marginRight="2dp" 
      android:text="A" 
      android:textSize="18dp" 
      android:focusable="false" 
      android:focusableInTouchMode="false" 
      android:gravity="center_vertical" 
      /> 
    </android.support.v7.widget.CardView> 
</LinearLayout> 

Voici l'adaptateur de logo qui affiche les images (LogoAdapter.java):

public class LogoAdapter extends RecyclerView.Adapter<LogoAdapter.LogoViewHolder> { 

    public static LogoAdapter adapter; 
    //declaration fo variables 
    List<LogoItems> brandLogo = new ArrayList<>(); 
    List<String> selector = new ArrayList<>(); 
    private AddBrandPage addBrandPage; 
    private Context context; 
    private CheckBox checkbox; 


    //the constructor 
    public LogoAdapter(List<LogoItems> brandLogo, Context context, AddBrandPage addBrandPage) { 
     this.brandLogo = brandLogo; 
     this.context = context; 
     this.addBrandPage = addBrandPage; 

    } 


    @Override 
    public LogoAdapter.LogoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.logo_items, parent, false); 
     LogoViewHolder logoViewHolder = new LogoViewHolder(view,addBrandPage); 
     return logoViewHolder; 
    } 

    @Override 
    public void onBindViewHolder(LogoAdapter.LogoViewHolder holder, int position) { 
     Picasso.with(context).load(brandLogo.get(position).getLogo()).into(holder.logo); 

    } 

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


    //viewholder class 
    public class LogoViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 

     //declare variables 
     private AddBrandPage addBrandPage; 
     private ImageView logo; 
     private CheckBox checkbox; 



     //ViewHolder constructor 
     public LogoViewHolder(View itemView, AddBrandPage addBrandPage) { 
      super(itemView); 

      //initialize variables inside the viewholder constructor 
      this.addBrandPage = addBrandPage; 
      logo = (ImageView) itemView.findViewById(R.id.img_logo); 
      checkbox = (CheckBox) itemView.findViewById(R.id.checkbox); 


      //set click listener for the checkbox 
      checkbox.setOnClickListener(this); 
      logo.setOnClickListener(this); 



     } 


     @Override 
     public void onClick(View v) { 
      int position = getAdapterPosition(); 
      addBrandPage.prepareSelection(v, position);//method call to populate an arraylist with selected items 


     } 
    } 
} 

Voici la mise en page XML des images (Logo_items.xml)

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:cardView="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/logo_container" 
    android:layout_width="match_parent" 
    android:layout_height="100dp" 
    android:background="@android:color/darker_gray" 
    android:gravity="center_vertical|center_horizontal" 
    android:orientation="vertical" 
    android:paddingBottom="10dp" 
    android:paddingLeft="10dp" 
    android:paddingRight="10dp" 
    android:paddingTop="10dp" 
    android:visibility="visible" 
    cardView:layout_collapseParallaxMultiplier="1.0"> 

    <android.support.v7.widget.CardView 
     android:layout_width="155dp" 
     android:layout_height="100dp" 
     android:layout_marginBottom="5dp" 
     android:layout_marginTop="5dp" 
     cardView:cardBackgroundColor="@android:color/white"> 


     <GridLayout 
      android:id="@+id/cardView" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:layout_gravity="center_horizontal|center_vertical" 
      android:orientation="vertical"> 


      <ImageView 
       android:id="@+id/img_logo" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:layout_column="1" 
       android:layout_gravity="center_horizontal|center_vertical" 
       android:layout_row="0" 
       android:paddingBottom="5dp" 
       android:paddingLeft="2.5dp" 
       android:paddingRight="2.5dp" 
       android:paddingTop="5dp"> 

      </ImageView> 

     </GridLayout> 

     <CheckBox 
      android:id="@+id/checkbox" 
      android:layout_width="30dp" 
      android:layout_height="30dp" 
      android:layout_marginLeft="130dp" 
      android:layout_marginTop="66dp" 
      android:onClick="addBrandpage.prepareSelection" 
      /> 

    </android.support.v7.widget.CardView> 

</LinearLayout> 

Voici le logcat:

06-16 09:16:24.404 12319-12324/com.test.test I/art: Do partial code cache collection, code=499KB, data=310KB 
06-16 09:16:24.429 12319-12324/com.test.test I/art: After code cache collection, code=499KB, data=315KB 
06-16 09:16:24.429 12319-12324/com.test.test I/art: Increasing code cache capacity to 2MB 
06-16 09:16:32.258 12319-12326/com.test.test W/art: Suspending all threads took: 13.640ms 
06-16 09:16:32.260 12319-12319/com.test.test I/Choreographer: Skipped 53 frames! The application may be doing too much work on its main thread. 

Répondre

0

j'ai pu résoudre le problème. Il ya deux OnClickListeners sur la page d'activité. Un pour le checkboxes et un pour l'index de l'alphabet. Ce qui se passait, c'est que lorsqu'une lettre de l'alphabet est cliquée, les deux OnClickListeners se déclenchent. Ainsi, au premier clic, l'alphabet OnClickListener s'exécute jusqu'à la fin et les mises à jour RecyclerView avec les images filtrées. Mais au second clic, alors qu'il semble exécuter la fonction, la fonction n'est pas complètement terminée car le programme est confondu avec le checkboxOnClickListener. La solution consiste à ajouter if (condition) à la méthode onClick afin que le programme sache à quel OnClickListener le clic s'applique. La modification apportée à la classe AlphaAdapter était la suivante:

@Override 
    public void onClick(View view) { 
     if (view == txt_alpha) { 
      int position = getAdapterPosition(); 
      String letter = alphaList.get(position).getLetter(); 
      addBrandPage.updateLogoDisplay(letter); 
     } 
    } 

Une modification similaire a été faite à la classe LogoAdapter.