Я работаю над приложением для 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;
}
}
любая помощь или совет?И спасибо