2016-08-10 6 views
0

Я делаю приложение и имеет recyclerview для показа пользовательского канала. Я использую кнопку переключения для портирования сообщений. Когда пользователь открывает приложение, он активирует кнопку, если статус уже понравился пользователю, который использует приложение, и пользователю также могут нравиться сообщения, прокручиваясь, как и другие социальные приложения.Android recycler view toggle button recycle issue

Проблема заключается в том, если кнопка переключения проверяется при прокрутке вниз других кнопок переключения, относится к другим должностям также получают чек.

адаптер класса

public class topNewsAdapter extends RecyclerView.Adapter<topNewsRowHolder> { 

     private ArrayList<topData> topDataList; 
     private Context context; 
     private Activity activity; 
     private RecyclerView recyclerView; 
     private View v; 
     protected String liked = "success"; 
     protected String expired = "Expired"; 




     public topNewsAdapter(ArrayList<topData> listItemList , Activity activity , RecyclerView view) { 

      this.topDataList = listItemList; 
      this.activity = activity; 
      this.recyclerView = view; 

     } 



     @Override 
     public topNewsRowHolder onCreateViewHolder(final ViewGroup parent, int viewType) { 
      v = LayoutInflater.from(parent.getContext()).inflate(R.layout.top_news_row, parent, false); 
      context = parent.getContext(); 
      return new topNewsRowHolder(v , activity); //passed activity 



     } 

     @Override 
     public void onBindViewHolder(final topNewsRowHolder holder, final int position) { 


      topData item = topDataList.get(position); 

      if(!(item == null)) { 

       holder.userName.setText(item.getUserName().toString()); 
       holder.timer.setText(item.getCreatedTime().toString()); 
       holder.status.setText(item.getStatus().toString()); 
       holder.fameCount.setText(item.getLikeCount().toString()); 
       holder.dislike_Count.setText(item.getDislike_Count().toString()); 
       holder.statusID.setText(item.getStatusID().toString()); 



       if(item.getLiked().equals(1)){ 
        holder.fameButton.setChecked(true); 
       }else if(item.getLiked().equals(0)){ 
        holder.fameButton.setChecked(false); 
       } 



       if(item.getDisliked().equals(1)){ 
        holder.disLikeButton.setChecked(true); 

       }else if(item.getDisliked().equals(0)){ 
        holder.disLikeButton.setChecked(false); 
       } 





       holder.fameButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
        @Override 
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
         if(isChecked){ 

          lRequester(holder.statusID.getText().toString() , "1" , holder.fameCount); 
          dRequester(holder.statusID.getText().toString() , "0" , holder.dislike_Count); 

          holder.fameButton.setChecked(true); 


         }else if(!isChecked){ 
          lRequester(holder.statusID.getText().toString() , "0" , holder.fameCount); 


         } 
        } 
       }); 


       holder.disLikeButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
        @Override 
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
         if(isChecked){ 
          dRequester(holder.statusID.getText().toString(), "1" ,holder.dislike_Count); 
          lRequester(holder.statusID.getText().toString() , "0" , holder.fameCount); 

          holder.fameButton.setChecked(false); 

         }else if(!isChecked){ 
          dRequester(holder.statusID.getText().toString() , "0" , holder.dislike_Count); 
         } 
        } 
       }); 







     } 



     } 













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


     @Override 
     public long getItemId(int position) { 
      return position; 
     } 




     public void lRequester(String id , String type, final TextView textview){ 
      Call<responseFD> request = handler.handlerClass.fame(data("u") , data("t") , id , type); 
      request.enqueue(new Callback<responseFD>() { 
       @Override 
       public void onResponse(Call<responseFD> call, Response<responseFD> response) { 
        if(!response.body().getResponse().isEmpty() && (response.body().getResponse() != null)) { 

         if (response.body().getResponse().equals(expired)) { 
          vlData.getInstance().terminateRunnable(); 
          reset(); 

         }else if (response.body().getResponse().equals(liked)) { 
          textview.setText(response.body().getLike_count().toString()); 

         } 


        } 

       } 

       @Override 
       public void onFailure(Call<responseFD> call, Throwable t) { 
        Toast.makeText(v.getContext(), "Something Gone Wrong", Toast.LENGTH_SHORT).show(); 

       } 
      }); 


     } 


     public void dRequester(String id , String type , final TextView textView){ 
      Call<responseFD> request = handler.handlerClass.disfame(data("u") , data("t") , id , type); 
      request.enqueue(new Callback<responseFD>() { 
       @Override 
       public void onResponse(Call<responseFD> call, Response<responseFD> response) { 
        if(!response.body().getResponse().isEmpty() && response.body().getResponse() != null) { 
         if (response.body().getResponse().equals(expired)) { 
          vlData.getInstance().terminateRunnable(); 
          reset(); 

         }else if (response.body().getResponse().equals(liked)) { 
          textView.setText(response.body().getDislike_Count().toString()); 

         } 
        } 


       } 

       @Override 
       public void onFailure(Call<responseFD> call, Throwable t) { 
        Log.d("data", "onFailure: " + t.getMessage()); 
       } 
      }); 







     } 


     public void reset(){ 

      Intent i = new Intent(activity , login.class); 
      activity.startActivity(i); 
      activity.finish(); 
     } 



    } 

Rowholder класс

public class topNewsRowHolder extends RecyclerView.ViewHolder { 

    protected TextView userName; 
    protected TextView timer; 
    protected TextView status; 
    protected ImageView profilePicHolder; 
    protected TextView fameCount; 
    protected TextView dislike_Count; 
    protected ToggleButton fameButton; 
    protected ToggleButton disLikeButton; 
    protected View v; 
    protected TextView statusID; 
    protected Activity activity; 
    protected RelativeLayout holderlayout; 




    public topNewsRowHolder(View view , Activity activity){ 
     super(view); 
     v = view; 
     this.activity = activity; 

     this.userName = (TextView)view.findViewById(R.id.usernameHolder); 
     this.timer = (TextView)view.findViewById(R.id.timeHolder); 
     this.status = (TextView)view.findViewById(R.id.status_user); 
     this.profilePicHolder = (ImageView)view.findViewById(R.id.profile_pic_holder); 
     this.fameCount = (TextView)view.findViewById(R.id.like_count); 
     this.dislike_Count = (TextView)view.findViewById(R.id.dislike_count); 
     this.fameButton = (ToggleButton)view.findViewById(R.id.fameButton); 
     this.disLikeButton = (ToggleButton)view.findViewById(R.id.dislikeButton); 
     this.statusID = (TextView)view.findViewById(R.id.statusID); 
     this.holderlayout = (RelativeLayout) view.findViewById(R.id.text); 







    } 


    } 

Я знаю, что это из-за переработки. Как решить эту проблему? Спасибо :)

+0

Вам нужно установить setLiked и setItemDisliked внутри проверки измененных прослушивателей и вызвать notifyitemChanged (getAdapterPosition()); Это должно решить. Дайте мне знать, если это поможет. –

+0

использовать 'SparseBooleanArray' [SparseBooleanArray] (https://developer.android.com/reference/android/util/SparseBooleanArray.html) –

+0

любой пример @vrundpurohit? –

ответ

0

Попробуйте следующее: RecyclerView нуждается в внешней переменной, чтобы отслеживать, какие элементы отмечены, а SparseBooleanArray будет работать, утомительно.

holder.fameButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
    @Override 
    public void onCheckedChanged(CompoundButton buttonView, boolean IsChecked) { 
     isChecked ? item.setIsLiked(1) : item.setIsLiked(0); 
     if(isChecked){ 
      lRequester(holder.statusID.getText().toString() , "1" , holder.fameCount); 
      dRequester(holder.statusID.getText().toString() , "0" , holder.dislike_Count); 
     } else if(!isChecked){ 
      lRequester(holder.statusID.getText().toString() , "0" , holder.fameCount); 
     } 
     } 
    }); 
+0

Чувак, я получаю эти значения от json не булевского массива. Он позволяет переключать кнопку, если пользователю уже понравился пост. если (item.getLiked(). Равен (1)) { владелец.fameButton.setChecked (true); } , если (item.getDisliked() равно (1).) { holder.disLikeButton.setChecked (истина); } –

+0

Не может ли пользователь любить и не любить при проверке кнопки переключения? –

+0

да, они делают. где источник этих значений используется в тройной форме. проверено ? item.setIsLiked (1): item.setIsLiked (0); ? –

0

Создайте шаблон брокера для управления в рамках фида контента.

Этот сломанный синглтон будет отслеживать каждый идентификатор элемента фида контента и отображать его в состояние (социальное или просто нравится) в хэш-карте. И каждый раз, когда возникает реакция (например,/unlike/dislike/undislike), происходящая с элементом фида контента, вы запускаете actian, используя этот Брокер, который также распространяется и отслеживает изменения локально. Вы должны реализовать транслятор или шаблон pub-sub, чтобы изменить пользовательский интерфейс об изменениях.

Предпочтительно использовать Поставщик контента с базой данных для хранения json, который вы получаете с веб-сервера.

Сообщите мне, если вам нужны дополнительные разъяснения.


SocialBroker.java

public class SocialBroker extends ISocialBroker { 
    //region <!-- Private properties --> 
    private static SocialBroker _instance; 
    private HashMap<UUID, SocialStatus> _map = new HashMap<>(); 
    //endregion 

    //region <!-- Singleton initializer --> 
    public static SocialBroker newInstance() { 
     if (_instance == null) { 
      _instance = new SocialBroker(); 
     } 
     return _instance; 
    } 

    private SocialBroker() {}; 
    //endregion 
    // The interface method implemented here 
} 

ISocialBroker.java

public interface ISocialBroker { 
    public synchronized SocialStatus save(String expiresAt, UUID id, boolean hasLiked, int numberOfLikes, int numberOfComments); 
    public SocialStatus lookup(UUID id); 
    public synchronized SocialStatus like(UUID id); 
    public synchronized SocialStatus unlike(UUID id); 

    public HashMap<UUID, SocialStatus> getMap(); 
    public void loadState(HashMap<UUID, SocialStatus> restoredSocialState); 
} 

OnReactionObserver.java

public interface OnReactionObserver { 
    void onLikeReaction(); 
} 

OnReactionPublisher.java

public interface OnReactionPublisher { 
    void attachObserver(OnReactionObserver... observer); 
    void notifyListeners(); 
} 

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

SocialStatus - это всего лишь модель для отслеживания информации, которая может быть сериализована, сохранена, синхронизирована с онлайн-службой.

Надеюсь, это указывает на то, что вы в правильном направлении.

+0

любой пример чувак? –

+0

@ JijoJohn просто обновил мой ответ выше. – anthonymonori