Элементы, добавленные несколько раз в RecyclerView с разбивкой на страницы - PullRequest
0 голосов
/ 21 сентября 2019

Я работаю над приложением для Android с Java.и теперь я должен сделать обмен сообщениями.Я использую RecyclerView для отображения элементов сообщений.Также мои сообщения Api работают с разбиением на страницы, каждый раз, когда я отправляю последний идентификатор, а сервер возвращает предыдущие 10 сообщений (размер страницы 10).Для заполнения RecyclerView я использую адаптер, но моя проблема в том, что элемент добавляется в RecyclerView несколько раз.

Я поставлю код активности и код адаптера

Моя активность:

public class ConversationsActivity extends RootActivity implements ConversationsAdapter.ConversationOnClickHandler {


RetrofitBuilder rB = new RetrofitBuilder();
IApi service = rB.retrofit.create(IApi.class);
String authorization;
RecyclerView rv;
ConversationsAdapter adapter;
ProgressBar progressBar;

LinearLayoutManager layoutManager;
//declare it as global var for future cancel refresh
private SwipeRefreshLayout swipeLayout;
boolean wasSwiped;


// initialise loading state
boolean mIsLoading,  mIsLastPage = false;

// amount of items you want to load per page
final int pageSize = 10;
int  mCurrentPage =0;
int lastId;
boolean f;
int p =1;


private AlphaAnimation buttonClick = new AlphaAnimation(1F, 0.7F);
int chatId, to;
String senderType, name, to_type;
TextView no_data;
Button btnActionBar11, send;
TextView tvActionBar;
EditText message;

Context context;

ArrayList<Conversation.Data> conversationArrayList = new ArrayList<>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_conversations);

    context = this;
    adapter = new ConversationsAdapter(this,context);

    Intent intent = getIntent();
    chatId = intent.getIntExtra("chatId",0);

    Intent intent1 = getIntent();
    senderType = intent1.getStringExtra("senderType");

    Intent intent2 = getIntent();
    name = intent2.getStringExtra("name");

    Intent intent3 = getIntent();
    to = intent3.getIntExtra("from",0);

    Intent intent4 = getIntent();
    to_type = intent4.getStringExtra("from_type");

    buttonClick.setDuration(500);
    authorization = checkAuthorization();

    setContentView(R.layout.activity_conversations);
    progressBar = (ProgressBar) findViewById(R.id.progress);

    tvActionBar = (TextView) findViewById(R.id.tvActionBar);
    tvActionBar.setText(name);
    layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
    layoutManager.setReverseLayout(true);
    adapter.setHasStableIds(true);

    // layoutManager.setStackFromEnd(true);

    rv = (RecyclerView) findViewById(R.id.ConversationList);
    no_data = (TextView) findViewById(R.id.no_data);
    message = (EditText) findViewById(R.id.message);
    send = (Button) findViewById(R.id.send);
    rv.setLayoutManager(layoutManager);
    btnActionBar11 = (Button) findViewById(R.id.btnActionBar11);

    btnActionBar11.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(getApplicationContext(), ChatActivity.class);
            startActivity(intent);
        }
    });

    send.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if(message.getText().length() > 0){
                sendMessage();
            }
        }
    });

    getConversation();

    rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            // number of visible items
            int visibleItemCount = ((LinearLayoutManager)recyclerView.getLayoutManager()).getChildCount();
            // number of items in layout
            int totalItemCount = ((LinearLayoutManager)recyclerView.getLayoutManager()).getItemCount();
            // the position of first visible item
            int firstVisibleItemPosition = ((LinearLayoutManager)recyclerView.getLayoutManager()).findFirstVisibleItemPosition();

            boolean isNotLoadingAndNotLastPage = !mIsLoading && !mIsLastPage;
            // flag if number of visible items is at the last
            boolean isAtLastItem = firstVisibleItemPosition + visibleItemCount >= totalItemCount;
            // validate non negative values
            boolean isValidFirstItem = firstVisibleItemPosition >= 0;
            // validate total items are more than possible visible items
            boolean totalIsMoreThanVisible = totalItemCount >= pageSize;
            // flag to know whether to load more
            boolean shouldLoadMore = isValidFirstItem && isAtLastItem && totalIsMoreThanVisible && isNotLoadingAndNotLastPage;

            if (shouldLoadMore) loadMoreItems(false);

        }
    });

    Intent intent11 = getIntent();
    wasSwiped = intent11.getBooleanExtra("wasSwiped",false);
    //where you initialize your views:
    swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);

    swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            wasSwiped = true;
            //your method to refresh content
            Intent intent = new Intent(getApplicationContext(), ConversationsActivity.class)
                    .putExtra("chatId", chatId)
                    .putExtra("senderType", senderType)
                    .putExtra("name",name)
                    .putExtra("from", to)
                    .putExtra("from_type", to_type)
                    .putExtra("wasSwiped", wasSwiped);
            startActivity(intent);

        }
    });


    if(wasSwiped){
        //don't forget to cancel refresh when work is done
        if(swipeLayout.isRefreshing()) {
            swipeLayout.setRefreshing(false);
        }

    }


}

@Override
public void onClickConversation(Conversation.Data conversation) {

}

@Override
public void onBackPressed() {
    super.onBackPressed();
    Intent intent = new Intent(getApplicationContext(), ChatActivity.class);
    startActivity(intent);
}

public void sendMessage(){


    Call<Message> call = service.sendMessage(authorization, to, to_type, message.getText().toString());
    call.enqueue(new Callback<Message>() {
        @Override
        public void onResponse(Call<Message> call, Response<Message> response) {
            if(response.isSuccessful()){
                if(response.body()!= null)
                    if(response.body().getData() != null);
                    message.setText("");
                    getConversation();
                 //
                //  adapter.notifyDataSetChanged();


            } else {
                if(response.body()!= null)
                    if(response.body().getMessage() != null)
                    Toast.makeText(getApplicationContext(),"error: " + response.body().getMessage(), Toast.LENGTH_LONG).show();

            }
        }

        @Override
        public void onFailure(Call<Message> call, Throwable t) {
            Toast.makeText(getApplicationContext(),"error: " + t.getMessage(), Toast.LENGTH_LONG).show();

        }
    });

}

public void getConversation(){
    Call<Conversation> call = service.getConversation(authorization,chatId,"LANDLORD");
    call.enqueue(new Callback<Conversation>() {
        @Override
        public void onResponse(Call<Conversation> call, Response<Conversation> response) {
            if(conversationArrayList != null)
                if(!conversationArrayList.isEmpty())
            conversationArrayList.clear();
            if(response.isSuccessful()){
                if(response.body()!= null)
                    if(response.body().getData() != null)
                        if(response.body().getData().size() > 0){
                            if (!conversationArrayList.isEmpty())

                          conversationArrayList.clear(); //The list for update recycle view

                            adapter.notifyDataSetChanged();
                            for(int i =0; i < response.body().getData().size(); i++){
                                conversationArrayList.add(response.body().getData().get(i));
                                if( i == ( response.body().getData().size() -1 ))
                                    lastId = conversationArrayList.get(conversationArrayList.size() - 1).getId();
                            }
                            progressBar.setVisibility(View.GONE);
                            if (conversationArrayList.isEmpty()) {
                                rv.setVisibility(View.GONE);
                                no_data.setVisibility(View.VISIBLE);
                            }
                            else {
                                rv.setVisibility(View.VISIBLE);
                                no_data.setVisibility(View.GONE);
                                progressBar.setVisibility(View.GONE);
                                configureRecyclerView(conversationArrayList);
                            }

                        } else {
                            progressBar.setVisibility(View.GONE);
                            no_data.setVisibility(View.VISIBLE);
                            rv.setVisibility(View.GONE);
                        }


            } else {
                Toast.makeText(getApplicationContext(),"error: " + response.body().getMessage(), Toast.LENGTH_LONG).show();

            }
        }

        @Override
        public void onFailure(Call<Conversation> call, Throwable t) {
            Toast.makeText(getApplicationContext(),"error: " + t.getMessage(), Toast.LENGTH_LONG).show();

        }
    });
}
private void configureRecyclerView(ArrayList chat) {
    rv = (RecyclerView) findViewById(R.id.ConversationList);
    rv.setHasFixedSize(true);
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
    linearLayoutManager.setReverseLayout(true);
    rv.setLayoutManager(linearLayoutManager);


    adapter = new ConversationsAdapter(this,context);
    adapter.setConversationData(chat);
    adapter.notifyDataSetChanged();

    rv.setAdapter(adapter);
}

private void loadMoreItems(boolean isFirstPage) {
    mIsLoading = true;
    f = isFirstPage;
    p = p +1;

    Call<Conversation> call = service.getConversationPagenation(authorization,chatId,senderType, lastId);
    call.enqueue(new Callback<Conversation>() {
        @Override
        public void onResponse(Call<Conversation> call, Response<Conversation> response) {
            if(response.isSuccessful()){
                if(response.body() != null)
                    if(response.body().getData()!= null) {

                      //  conversationArrayList.clear();
                        for(int i =0; i < response.body().getData().size(); i++){
                            conversationArrayList.add(response.body().getData().get(i));

                            if( i == ( response.body().getData().size() -1 ))
                                lastId = conversationArrayList.get(conversationArrayList.size() - 1).getId();
                        }

                        progressBar.setVisibility(View.GONE);


                        if(conversationArrayList == null){
                            rv.setVisibility(View.GONE);
                            no_data.setVisibility(View.VISIBLE);
                            return;
                        }

                        else if (!f) {
                            if (!conversationArrayList.isEmpty())


                                adapter.notifyDataSetChanged();
                            adapter.addAll(conversationArrayList);
                      //      conversationArrayList.clear(); //The list for update recycle view


                        }
                        else {
                            rv.setVisibility(View.VISIBLE);
                            no_data.setVisibility(View.GONE);
                            configureRecyclerView(conversationArrayList);



                        }

                        if(conversationArrayList.size() > 0)
                            lastId = conversationArrayList.get(conversationArrayList.size() - 1).getId();

                        mIsLoading = false;
                        mIsLastPage = mCurrentPage == lastId;
                        mCurrentPage = lastId;

                    }
            }
        }

        @Override
        public void onFailure(Call<Conversation> call, Throwable t) {
            Log.e("SomeActivity", t.getMessage());

        }
    });


}

public String checkAuthorization(){
    SharedPreferences settings = getSharedPreferences("log",0);
    return settings.getString("Authorization", null);
}

}

Мой адаптер:

public class ConversationsAdapter extends
    RecyclerView.Adapter<ConversationsAdapter.ConversationsAdapterViewHolder> {
private Context context;
private ArrayList<Conversation.Data> mConversation;
private ConversationsAdapter.ConversationOnClickHandler mConversationOnClickHandler;
private static SharedPreferences pref;


public ConversationsAdapter(ConversationsAdapter.ConversationOnClickHandler conversationOnClickHandler, Context _context) {
   mConversationOnClickHandler = conversationOnClickHandler;

    pref = _context.getSharedPreferences("log", Context.MODE_PRIVATE);

}


public void setConversationData(ArrayList<Conversation.Data> conversation) {
    mConversation = conversation;
    notifyDataSetChanged();
}



public void addAll(ArrayList<Conversation.Data> newList) {
    int lastIndex = mConversation.size() - 1;
    mConversation.addAll(newList);
    notifyItemRangeInserted(lastIndex, newList.size());
}

@Override
public ConversationsAdapter.ConversationsAdapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    context = parent.getContext();
    LayoutInflater inflater = LayoutInflater.from(context);

    // Inflate the custom layout
    View contactView = inflater.inflate(R.layout.row_msg, parent, false);

    // Return a new holder instance
    ConversationsAdapter.ConversationsAdapterViewHolder viewHolder = new ConversationsAdapter.ConversationsAdapterViewHolder(contactView);
    return viewHolder;
}

@Override
public void onBindViewHolder(ConversationsAdapter.ConversationsAdapterViewHolder viewHolder, int position) {
    Conversation.Data conversation = mConversation.get(position);
    TextView tv1 = viewHolder.tv1;
    TextView tv2 = viewHolder.tv2;

  //  SharedPreferences preferences = context.getSharedPreferences("log", Context.MODE_PRIVATE);
    String agentId = pref.getString("agentId", "");

    String from_type = conversation.getFromType();
    int from = conversation.getFrom();

    if((agentId.equals(String.valueOf(from))) && from_type.equals("AGENT")){
        tv2.setVisibility(View.GONE);
        tv1.setVisibility(View.VISIBLE);
        tv1.setText(conversation.getBody());
    }
    else {
        tv2.setVisibility(View.VISIBLE);
        tv1.setVisibility(View.GONE);

        tv2.setText(conversation.getBody());
    }

}

// Returns the total count of items in the list
@Override
public int getItemCount() {
    if(mConversation == null) {
        return 0;
    }

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

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


@Override
public void setHasStableIds(boolean hasStableIds) {
    super.setHasStableIds(hasStableIds);
}

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

    public final TextView tv1;
    public final TextView tv2;




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

        tv1 = (TextView) view.findViewById(R.id.tvMsgR);
        tv2 = (TextView) view.findViewById(R.id.tvMsgL);

        view.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        int position = getAdapterPosition();
       Conversation.Data selectedNotifiction = mConversation.get(position);
        mConversationOnClickHandler.onClickConversation(selectedNotifiction);
    }
}

public interface ConversationOnClickHandler {
    void onClickConversation(Conversation.Data conversation);

}


public long myTimeInMillis(String givenDateString ){
    //  String givenDateString = "Tue Apr 23 16:08:28 GMT+05:30 2013";
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    long timeInMilliseconds = 0;
    try {
        Date mDate = sdf.parse(givenDateString);
        timeInMilliseconds = mDate.getTime();
        //    System.out.println("Date in milli :: " + timeInMilliseconds);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return timeInMilliseconds;
}

}

любая помощь или совет?И спасибо

1 Ответ

0 голосов
/ 22 сентября 2019

в вашей функции addAll () класса ConversationsAdapter

int lastIndex = mConversation.size() - 1;
mConversation.clear();
mConversation.addAll(newList);
notifyItemRangeInserted(lastIndex, newList.size());

это должно сработать

...