RecyclerView filled with Objects from SharedPreferences is slow and laggy - android

I am building an app which has a RecyclerView which holds Objects that are retrieved from SharedPreferences.
Unfortunately the RecyclerView is lagging when it is binded.
This is my Adapter
public class ShiftAdapter extends RecyclerView.Adapter<ShiftAdapter.ViewHolder>{
private List<Shift> mDataSet;
private Context mContext;
private static final String TAG = "ShiftAdapter";
public int previousExpandedPosition = -1;
public int mExpandedPosition = -1;
private static SharedPreferences mPrefs;
private LinearLayout mShiftIn;
private LinearLayout mShiftOut;
private Boolean isStart;
private Date shiftIn;
private Date shiftOut;
private Date mDate;
public EditText mshiftInText;
public EditText mshiftOutText;
public Date date;
public ShiftAdapter(Context context, List<Shift> list) {
mDataSet = list;
mContext = context;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mDate;
public TextView mTime;
public TextView mPay;
public RelativeLayout mRelativeLayout;
public LinearLayout mExepandableLayout;
public Date mshiftIn;
public Date mshiftOut;
public EditText mshiftInText;
public EditText mshiftOutText;
public Button mUpdateButton;
public Button mDeleteButton;
public ViewHolder(View v) {
super(v);
mDate = (TextView) v.findViewById(R.id.date_TV);
mTime = (TextView) v.findViewById(R.id.time_TV);
mPay = (TextView) v.findViewById(R.id.pay_TV);
mRelativeLayout = (RelativeLayout) v.findViewById(R.id.rel_layout);
mExepandableLayout = (LinearLayout) v.findViewById(R.id.expandableLayout);
mshiftInText = (EditText) v.findViewById(R.id.setShiftIn);
mshiftOutText = (EditText) v.findViewById(R.id.setShiftOut);
mUpdateButton = (Button) v.findViewById(R.id.updateButton);
mDeleteButton = (Button) v.findViewById(R.id.deleteButton);
}
}
#Override
public ShiftAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(mContext)
.inflate(R.layout.shift, parent, false);
ViewHolder vh = new ViewHolder(itemView);
return vh;
}
//TODO:Bind all the view elements to Shift Properties
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int i) {
// Format double
String hours = new DecimalFormat("##.##").format(mDataSet.get(i).getHours());
String pay = new DecimalFormat("##.##").format(mDataSet.get(i).getPay());
//set the Text
holder.mTime.setText(hours);
holder.mDate.setText(mDataSet.get(i).dateToString());
holder.mPay.setText(pay);
Log.d(TAG, "onBindViewHolder: called");
// new AsyncTask<>().ex
//Expand mExapndableLayout
final int position = i;
final boolean isExpanded = position ==mExpandedPosition;
holder.mExepandableLayout.setVisibility(isExpanded?View.VISIBLE:View.GONE);
holder.itemView.setActivated(isExpanded);
// //set shift Times
// shiftIn = mDataSet.get(position).getInDate();
// shiftOut = mDataSet.get(position).getInDate();
if (isExpanded)
previousExpandedPosition = position;
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mExpandedPosition = isExpanded ? -1:position;
notifyItemChanged(previousExpandedPosition);
notifyItemChanged(position);
}
});
//fill expandable layout
holder.mshiftInText.setText(mDataSet.get(position).fullTimeToString(0));
final EditText in = holder.mshiftInText;
final EditText out = holder.mshiftOutText;
//edit mShiftIn Text
holder.mshiftInText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
isStart =true;
timePickerDialog(in,out);
}
});
holder.mshiftOutText.setText(mDataSet.get(position).fullTimeToString(1));
//edit MshiftOut Text
holder.mshiftOutText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
isStart =false;
timePickerDialog(in,out);
}
});
//updateButton onClick
holder.mUpdateButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
shiftIn = mDataSet.get(position).getInDate();
shiftOut = mDataSet.get(position).getOutDate();
if(Validate.getValidate().isDateValid(shiftIn,shiftOut)) {
SharedPrefs.getInstance(mContext).editShift(newShift(shiftIn, shiftOut),Integer.toString(position));
int length = SharedPrefs.getInstance(mContext).getLength() - 1;
if (SharedPrefs.getInstance(mContext).getShift(length) != null) {
Log.d(TAG, "Edit Shift onClick: Success");
SharedPrefs.getInstance(mContext).saveShiftList(SharedPrefs.getInstance(mContext).sortList(SharedPrefs.getInstance(mContext).getShiftList()));
ShiftsFragment.updateUI();
Toast.makeText(mContext, "success", Toast.LENGTH_SHORT).show();
}
} else {
mShiftOut.setBackgroundResource(R.drawable.red_border);
Toast.makeText(mContext, "error", Toast.LENGTH_SHORT).show(); }
} catch(Exception e){
Log.d(TAG, "onDateSelected: "+e.toString());
Toast.makeText(mContext,"update FAIL", Toast.LENGTH_SHORT).show();
}
// update the Shift
}
});
holder.mDeleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
areYouSure(mExpandedPosition);
}
});
}
#Override
public int getItemCount() {
return mDataSet.size();
}
public Date timePickerDialog(EditText in,EditText out) {
mshiftInText = in;
mshiftOutText = out;
new SingleDateAndTimePickerDialog.Builder(mContext)
.title(mContext.getResources().getString(R.string.choose_time))
.displayListener(new SingleDateAndTimePickerDialog.DisplayListener() {
#Override
public void onDisplayed(SingleDateAndTimePicker picker) {
if(!isStart) {
date = mDate;
}
}
}).defaultDate(returnDate(date))
.listener(new SingleDateAndTimePickerDialog.Listener() {
#Override
public void onDateSelected(Date date) {
mDate = date;
if (isStart) {
updateShiftIn(mDate);
mshiftInText.setText(dateToString(mDate));
} else {
updateShiftOut(mDate);
mshiftOutText.setText(dateToString(mDate));
}
}
}).display();
return mDate;
}
public String dateToString(Date date)
{
DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm");
String string = df.format(date);
return string;
}
private void updateShiftIn(Date date) {
shiftIn = date;
}
private void updateShiftOut(Date date) {
shiftOut = date;
}
private Date returnDate(Date date)
{
if(date!=null)
{
return date;
}
else return mDate;
}
private void areYouSure(int i)
{
final String position = Integer.toString(i);
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which){
case DialogInterface.BUTTON_POSITIVE:
Log.d(TAG, "onClick: isSure=true;");
SharedPrefs.getInstance(mContext).removeShift(position);
ShiftsFragment.updateUI();
case DialogInterface.BUTTON_NEGATIVE:
Log.d(TAG, "onClick: isSure= false");
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setMessage(mContext.getResources().getString(R.string.are_you_sure)).setPositiveButton(mContext.getResources().getString(R.string.confirm), dialogClickListener)
.setNegativeButton(mContext.getResources().getString(R.string.cancel), dialogClickListener).show();
}
private Shift newShift(Date start,Date stop)
{
int id = SharedPrefs.getInstance(mContext).getLength();
Shift shift = new Shift(dateToCalendar(start),dateToCalendar(stop),id);
return shift;
}
and this is the Fragment that has the RecyclerView
public class ShiftsFragment extends Fragment {
private Toolbar mToolbar;
private TimePicker timePicker1;
private List<Shift> shiftList = new ArrayList<>();
private RecyclerView recyclerView;
private RelativeLayout relativeLayout;
private RecyclerView.LayoutManager layoutManager;
private LinearLayout mShiftIn;
private LinearLayout mShiftOut;
private Context mContext;
private ShiftAdapter mAdapter;
private MenuItem mAdd;
private Menu optionsMenu;
private LinearLayout mShiftAddLL;
private SharedPreferences mPrefs;
private static FragmentManager mFragmentManager;
private static final String TAG = "ShiftsFragment";
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
Log.d(TAG,"Clicked");
final View view = inflater.inflate(R.layout.shifts_layout,container,false);
mToolbar = view.findViewById(R.id.topbar);
mToolbar.inflateMenu(R.menu.toolbarmenu);
mShiftAddLL = view.findViewById(R.id.add_shiftLayout);
mAdd = mToolbar.getMenu().getItem(0);
timePicker1 = (TimePicker) view.findViewById(R.id.timePicker);
mFragmentManager = getFragmentManager();
//TODO:Add a summary bar on the bottom.
//get the context
mContext = getContext();
recyclerView = (RecyclerView) view.findViewById(R.id.shift_list);
// Define a layout for RecyclerView
layoutManager = new GridLayoutManager(mContext,1);
recyclerView.setLayoutManager(layoutManager);
// Initialize a new Shift array
List<Shift> shiftList = initShifts();
Log.d(TAG,"shift array initiated");
// Initialize an array list from array
// Initialize a new instance of RecyclerView Adapter instance
mAdapter = new ShiftAdapter(mContext,shiftList);
// Set the adapter for RecyclerView
recyclerView.setAdapter(mAdapter);
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(true);
//Menu add button onClick
//Opens Add_Shift_Fragment
mAdd.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
Fragment selectedFragment = new Add_Shift_Fragment();
getFragmentManager().beginTransaction().replace(R.id.fragment_container,
selectedFragment).commit();
return false;
}
});
return view;
}
//Initializes the Shift list from SharedPreferences and returns it.
private List<Shift> initShifts() {
return SharedPrefs.getInstance(mContext).getShiftList();
}
public static void updateUI()
{
Fragment selectedFragment = new ShiftsFragment();
mFragmentManager.beginTransaction().replace(R.id.fragment_container,
selectedFragment).commit();
}
}
Everytime i launch the ShiftsFragment there are some frame skips, and the scrolling is choppy and laggy.
Maybe my SharedPreferences handling is what is slowing things down?
public class SharedPrefs {
private static SharedPrefs mSharedPrefs;
private SharedPreferences mPrefs;
private SharedPreferences.Editor mPrefsEditor;
protected Context mContext;
public static final String ID = "shiftList";
private SharedPrefs(Context context) {
mContext = context;
mPrefs = context.getSharedPreferences(ID, Context.MODE_PRIVATE);
mPrefsEditor = mPrefs.edit();
}
public static SharedPrefs getInstance(Context context) {
if (mSharedPrefs == null) {
mSharedPrefs = new SharedPrefs(context.getApplicationContext());
}
return mSharedPrefs;
}
public void saveShiftList(List<Shift> shiftList) {
Gson gson = new Gson();
String json = gson.toJson(shiftList);
mPrefsEditor.putString(ID, json);
mPrefsEditor.apply();
}
public void addShift (Shift shift)
{
List<Shift> shiftList= getShiftList();
shiftList.add(shift);
saveShiftList(shiftList);
}
//Replaced the shift#id with shift
public void editShift(Shift shift,String id)
{
removeShift(id);
addShift(shift);
}
public void removeShift(String id) {
List<Shift> shiftList = getShiftList();
int pos = Integer.parseInt(id);
shiftList.remove(pos);
saveShiftList(shiftList);
}
public void removeShift(int id) {
List<Shift> shiftList = getShiftList();
shiftList.remove(id);
saveShiftList(shiftList);
}
public Shift getShift(int id) {
Gson gson = new Gson();
List<Shift> shiftList;
String json = mPrefs.getString(ID, null);
Type type = new TypeToken<List<Shift>>() {
}.getType();
shiftList = gson.fromJson(json, type);
Shift shift = shiftList.get(id);
return shift;
}
public List<Shift> getShiftList() {
Gson gson = new Gson();
List<Shift> shiftList;
String json = mPrefs.getString(ID, null);
Type type = new TypeToken<List<Shift>>() {
}.getType();
shiftList = gson.fromJson(json, type);
if (shiftList!=null) {
return shiftList;
} else{
shiftList = new ArrayList<>();
return shiftList;
}
}
public List<Shift> sortList(List<Shift> shiftList)
{
Collections.sort(shiftList, new Comparator<Shift>() {
public int compare(Shift shift1, Shift shift2) {
if (shift1.getShiftStart() == null || shift2.getShiftStart() == null)
return 0;
return shift1.getShiftStart().compareTo(shift2.getShiftStart());
}
});
return shiftList;
}
public int getLength()
{
return getShiftList().size();
}
}
I have only found this problem with image loading, not just Strings from Object from SharedPrefs.

Related

RecyclerView messes up when scrolling

I never asked any question before but hope you'll get my point.
I am making a chat app in which I am using a RecyclerView to show messages. The problem is when I scroll the RecyclerView some of the items disappear from the top and the whole items messes up when I try to add a message it doesn't even scroll to bottom nor added in the ListView.
Here is my RecyclerView:
<android.support.v7.widget.RecyclerView
android:id="#+id/conversation_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:layout_above="#id/typingConversationLayout"
android:layout_below="#id/topLayout_conversation_activity"
android:layout_marginBottom="-5dp"
android:paddingBottom="7dp" />
Initializing and setting the RecycerView:
linearLayoutManager = new LinearLayoutManager(this);
adapter = new ConversationRecyclerViewAdapter();
conversationRecyclerView.setAdapter(adapter);
conversationRecyclerView.setLayoutManager(linearLayoutManager);
linearLayoutManager.setStackFromEnd(true);
conversationRecyclerView.setHasFixedSize(true);
conversationRecyclerView.setNestedScrollingEnabled(false);
Here is my Adapter class:
private class ConversationRecyclerViewAdapter
extends RecyclerView.Adapter<ConversationRecyclerViewAdapter.ConversationViewHolder> {
#NonNull
#Override
public ConversationViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
Log.d(TAG, "onCreateViewHolder: Users Find started");
View conversationsView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.layout_message_received, parent, false);
return new ConversationViewHolder(conversationsView);
}
#Override
public void onBindViewHolder(#NonNull final ConversationViewHolder holderConversation, int i) {
Log.d(TAG, "onBindViewHolder: Users Find started at position is " + i);
final int position = holderConversation.getAdapterPosition();
if (mOwnUser_1.get(position)) {
holderConversation.receivedMsgLayout.setVisibility(View.GONE);
holderConversation.sentProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.sentMsg.setText(mUserText_3.get(position));
} else {
holderConversation.sentMsgLayout.setVisibility(View.GONE);
holderConversation.receivedProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.receivedMsg.setText(mUserText_3.get(position));
}
Log.d(TAG, "onBindViewHolder: completed at " + position);
}
#Override
public int getItemCount() {
return mOwnUser_1.size();
}
public class ConversationViewHolder extends RecyclerView.ViewHolder {
RelativeLayout receivedMsgLayout, sentMsgLayout;
EmojiTextView receivedMsg, sentMsg;
CircleImageView receivedProfileImg, sentProfileImg;
public ConversationViewHolder(#NonNull View v) {
super(v);
receivedMsgLayout = v.findViewById(R.id.received_message_layout);
sentMsgLayout = v.findViewById(R.id.sent_message_layout);
receivedMsg = v.findViewById(R.id.received_message_text);
sentMsg = v.findViewById(R.id.sent_message_text);
receivedProfileImg = v.findViewById(R.id.received_message_user__profile_image);
sentProfileImg = v.findViewById(R.id.sent_message_user__profile_image);
}
}
}
Here I am adding data to ListView and displaying to the RecyclerView:
sendBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String msg = editText.getText().toString().trim();
if (TextUtils.isEmpty(msg)) {
editText.setError("Please add a message");
editText.requestFocus();
} else {
Log.d(TAG, "onClick: send Btn ADDED TEXT.. ");
mOwnUser_1.add(user);
mUserProfileImg_2.add(image);
mUserText_3.add(message);
editText.setText("");
editText.requestFocus();
adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);
}
}
});
I don't know what i am doing wrong but it does not seem to work as i wanted.
Update Code:
The three listviews:
private ArrayList<Boolean> mOwnUser_1 = new ArrayList<>();
private ArrayList<Integer> mUserProfileImg_2 = new ArrayList<>();
private ArrayList<String> mUserText_3 = new ArrayList<>();
And the way of adding data to adapter:
mOwnUser_1.add(true);
mUserProfileImg_2.add(R.drawable.boy);
mUserText_3.add(edittext.getText().toString().trim());
adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);
My Whole Conversation Activity Class:
public class ConversationActivity extends AppCompatActivity {
private static final String TAG = "ConversationActivity";
private EditText editText;
private LinearLayout linearLayout;
private LinearLayoutManager linearLayoutManager;
private ImageView sendBtn;
private ImageView emojiImage;
private View rootView;
private Boolean popUpShown = false;
private Boolean micShown = false;
private ImageView micBtn;
private RelativeLayout micLayout;
private RecyclerView conversationRecyclerView;
// Array Lists for Find USERS
private ArrayList<Boolean> mOwnUser_1 = new ArrayList<>();
private ArrayList<Integer> mUserProfileImg_2 = new ArrayList<>();
private ArrayList<String> mUserText_3 = new ArrayList<>();
private ConversationRecyclerViewAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate: started");
super.onCreate(savedInstanceState);
EmojiManager.install(new TwitterEmojiProvider());
setContentView(R.layout.activity_conversation);
editText = findViewById(R.id.conversationEditText);
linearLayout = findViewById(R.id.optionsOther);
emojiImage = findViewById(R.id.emojiIconOther);
rootView = findViewById(R.id.root_view_conversation);
micBtn = findViewById(R.id.microphoneBtn);
micLayout = findViewById(R.id.microphoneLayout);
conversationRecyclerView = findViewById(R.id.conversation_recyclerView);
sendBtn = findViewById(R.id.sendBtnConversation);
if (!(Build.VERSION.SDK_INT >= 21))
findViewById(R.id.typingConversationLayout).setBackgroundResource(R.drawable.edit_text_conversation_background_below_api);
sendBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String msg = editText.getText().toString().trim();
if (TextUtils.isEmpty(msg)) {
editText.setError("Please add a message");
editText.requestFocus();
} else {
Log.d(TAG, "onClick: send Btn ADDED TEXT.. ");
addData(true, R.drawable.boy0, msg);
}
}
});
initConversationArrayList();
}
private void addData(Boolean user, int image, String message) {
mOwnUser_1.add(user);
mUserProfileImg_2.add(image);
mUserText_3.add(message);
editText.setText("");
editText.requestFocus();
adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);
}
private void initConversationArrayList() {
Log.d(TAG, "initConversationArrayList: created");
mOwnUser_1.add(true);
mUserProfileImg_2.add(R.drawable.boy0);
mUserText_3.add("Hello How are you?");
Log.d(TAG, "initConversationArrayList: completed");
initConversationRecyclerView();
}
private void initConversationRecyclerView() {
Log.d(TAG, "initConversationRecyclerView: started");
linearLayoutManager = new LinearLayoutManager(this);
adapter = new ConversationRecyclerViewAdapter();
conversationRecyclerView.setAdapter(adapter);
conversationRecyclerView.setLayoutManager(linearLayoutManager);
linearLayoutManager.setStackFromEnd(true);
conversationRecyclerView.setHasFixedSize(true);
conversationRecyclerView.setNestedScrollingEnabled(false);
Log.d(TAG, "initConversationRecyclerView: completed");
}
Currently I am also working on chat module, let me show you how am I doing this. I am going to show you in steps.
Step 1: make two separate layout for recyclerview items, one for message that has been sent from your side and one for message received from another side.
Step 2 : make two view holders to populate different layout according to your scenario, made in above step, like this:
public class ChatNewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Chat> chats;
public ChatNewAdapter(List<Chat> chats) {
this.chats = chats;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == 0) {
View viewSend = (View) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_send, parent, false);
return new ViewHolderSend(viewSend);
} else {
View viewReceive = (View) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_received, parent, false);
return new ViewHolderReceive(viewReceive);
}
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case 0:
ViewHolderSend viewHolderSend = (ViewHolderSend) holder;
viewHolderSend.messageSend.setText(chats.get(position).getMessage());
break;
case 1:
ViewHolderReceive viewHolderReceive = (ViewHolderReceive) holder;
viewHolderReceive.messageReceived.setText(chats.get(position).getMessage());
break;
}
}
#Override
public int getItemCount() {
return chats.size();
}
#Override
public int getItemViewType(int position) {
if (chats != null && !chats.get(position).fromAdmin) {
return 0;
} else
return 1;
}
class ViewHolderSend extends RecyclerView.ViewHolder {
TextView messageSend;
public ViewHolderSend(View itemView) {
super(itemView);
messageSend = (TextView) itemView.findViewById(R.id.messageSend);
}
}
class ViewHolderReceive extends RecyclerView.ViewHolder {
TextView messageReceived;
public ViewHolderReceive(View itemView) {
super(itemView);
messageReceived = (TextView) itemView.findViewById(R.id.messageReceived);
}
}
public int addMessages(Chat chat) {
chats.add(chat);
notifyDataSetChanged();
return chats.size();
}
Step 3 : now in your activity:
public class Test extends AppCompatActivity {
RecyclerView chatList;
RecyclerView.LayoutManager mLayoutManager;
ChatNewAdapter adapter;
ImageView sendButton;
EditText messageEditText;
boolean keyboardUp = false;
boolean isRunning = false;
ArrayList<Chat> chats;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
isRunning = true;
setUpComponents();
}
public void setUpComponents() {
chatList = (RecyclerView) findViewById(R.id.chat_list);
chatList.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
chatList.setLayoutManager(mLayoutManager);
messageEditText = (EditText) findViewById(R.id.messageText);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
sendButton = (ImageView) findViewById(R.id.send);
adapter = new ChatNewAdapter(chats);
chatList.setAdapter(adapter);
chatList.scrollToPosition(chatList.getAdapter().getItemCount() - 1);
messageEditText.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (keyboardShown(messageEditText.getRootView())) {
Log.d("keyboard", "keyboard UP");
if (keyboardUp == false) {
if (chats.size() > 0)
chatList.smoothScrollToPosition(chats.size() + 1);
keyboardUp = true;
}
} else {
Log.d("keyboard", "keyboard Down");
keyboardUp = false;
}
}
});
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final String message = messageEditText.getText().toString().trim();
if (!message.equals("")) {
Chat chat = new Chat();
String name = message;
chat.setMessage(name);
messageEditText.setText("");
adapter.addMessages(chat);
chatList.scrollToPosition(chatList.getAdapter().getItemCount() - 1);
} else {
Log.d("sending message Error", "error fetching dates");
}
}
});
}
private boolean keyboardShown(View rootView) {
final int softKeyboardHeight = 100;
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
int heightDiff = rootView.getBottom() - r.bottom;
return heightDiff > softKeyboardHeight * dm.density;
}
And this is my model class, ignore #PrimaryKey and #Required annotation it just because I am using Realm for local DB. In your case you wont required these annotation.
public class Chat extends RealmObject {
#PrimaryKey
#Required
public Long id;
public boolean fromAdmin;
#Required
public String message;
public int type;
public boolean isRead;
public boolean isSent;
public Date date;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public boolean isFromAdmin() {
return fromAdmin;
}
public void setFromAdmin(boolean fromAdmin) {
this.fromAdmin = fromAdmin;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public boolean isRead() {
return isRead;
}
public void setRead(boolean read) {
isRead = read;
}
public boolean isSent() {
return isSent;
}
public void setSent(boolean sent) {
isSent = sent;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
I hope it will be helpful for you, you can ask further if you want to know anything else related to code.
RecyclerView as the name stands recycles the views. When binding data to a view, you need to ensure you set or reset all views that are touched in the adapter. Messups typically occur when there's data that is set only conditionally for some but not all items.
In particular:
if (mOwnUser_1.get(position)) {
holderConversation.receivedMsgLayout.setVisibility(View.GONE);
holderConversation.sentProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.sentMsg.setText(mUserText_3.get(position));
} else {
holderConversation.sentMsgLayout.setVisibility(View.GONE);
holderConversation.receivedProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.receivedMsg.setText(mUserText_3.get(position));
}
Both of these branches will need to reset the other layout back to visible.
Anyway with this kind of two-layout approach you are likely better off by having them as separate view types in your adapter. See How to create RecyclerView with multiple view type?

add integer values selected by checkbox

TestListModel.class
public class TestListModel {
private String testlist_id;
private String test_price;
private String test_name;
private boolean isSelected;
public TestListModel(String testlist_id, String test_price, String test_name,boolean isSelected) {
this.testlist_id = testlist_id;
this.test_price = test_price;
this.test_name = test_name;
this.isSelected = isSelected;
}
public String getTestlist_id() {
return testlist_id;
}
public void setTestlist_id(String testlist_id) {
this.testlist_id = testlist_id;
}
public String getTest_price() {
return test_price;
}
public void setTest_price(String test_price) {
this.test_price = test_price;
}
public String getTest_name() {
return test_name;
}
public void setTest_name(String test_name) {
this.test_name = test_name;
}
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean isSelected) {
this.isSelected = isSelected;
}
}
JsonResponse.java
public class JSONResponse {
private TestListModel[] result;
public TestListModel[] getResult() {
return result;
}
public void setResult(TestListModel[] result) {
this.result = result;
}
}
HealthActivity.java
public class HealthServicesActivity extends AppCompatActivity implements View.OnClickListener {
/*
*Api call
* */
private RecyclerView recyclerView;
private ArrayList<TestListModel> data;
private RecyclerAdapter madapter;
private Button submitButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_health_services);
ButterKnife.bind(this);
sharePreferenceManager = new SharePreferenceManager<>(getApplicationContext());
submitButton=(Button) findViewById(R.id.submit_button);
showcenterid(sharePreferenceManager.getUserLoginData(LoginModel.class));
initViews();
submitButton.setOnClickListener(this);
/*
* On Click Listner
* */
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.submit_button:
int totalAmount = 0;
int totalPrice = 0;
String testName = "";
String testPrice="";
int count = 0;
List<TestListModel> stList = ((RecyclerAdapter) madapter)
.getTestList();
for (int i = 0; i < stList.size(); i++) {
TestListModel singleStudent = stList.get(i);
//AmountCartModel serialNumber = stList.get(i);
if (singleStudent.isSelected() == true) {
testName = testName + "\n" + singleStudent.getTest_name().toString();
testPrice = testPrice+"\n" + singleStudent.getTest_price().toString();
count++;
totalAmount = Integer.parseInt(stList.get(i).getTest_price());
totalPrice = totalPrice + totalAmount;
}
}
Toast.makeText(HealthServicesActivity.this,
"Selected Lists: \n" + testName+ "" + testPrice, Toast.LENGTH_LONG)
.show();
Intent in= new Intent(HealthServicesActivity.this, AmountCartActivity.class);
in.putExtra("test_name", testName);
in.putExtra("test_price", testPrice);
//in.putExtra("total_price",totalPrice);
in.putExtra("total_price", totalPrice);
in.putExtra("serialNumber", count);
startActivity(in);
finish();
break;
/** back Button Click
* */
case R.id.back_to_add_patient:
startActivity(new Intent(getApplicationContext(), PatientActivity.class));
finish();
break;
default:
break;
}
}
/** show center Id in action bar
* */
#Override
protected void onResume() {
super.onResume();
showcenterid(sharePreferenceManager.getUserLoginData(LoginModel.class));
}
private void showcenterid(LoginModel userLoginData) {
centerId.setText(userLoginData.getResult().getGenCenterId());
centerId.setText(userLoginData.getResult().getGenCenterId().toUpperCase());
deviceModeName.setText(userLoginData.getResult().getDeviceModeName());
}
private void initViews() {
recyclerView = (RecyclerView)findViewById(R.id.test_list_recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
loadJSON();
}
private void loadJSON() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(" http://192.168.1.80/aoplnew/api/")
//
.baseUrl("https://earthquake.usgs.gov/fdsnws/event/1/query?")
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiInterface request = retrofit.create(ApiInterface.class);
Call<JSONResponse> call = request.getTestLists();
call.enqueue(new Callback<JSONResponse>() {
#Override
public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {
JSONResponse jsonResponse = response.body();
data = new ArrayList<>(Arrays.asList(jsonResponse.getResult()));
madapter = new RecyclerAdapter(data);
recyclerView.setAdapter(madapter);
}
#Override
public void onFailure(Call<JSONResponse> call, Throwable t) {
Log.d("Error",t.getMessage());
}
});
}
HealthRecyclerAdapter.java
public class RecyclerAdapter extends
RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private ArrayList<TestListModel> android;
public RecyclerAdapter(ArrayList<TestListModel> android) {
this.android = android;
}
#Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.test_list_row,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(RecyclerAdapter.ViewHolder holder, final int position) {
holder.test_name.setText(android.get(position).getTest_name());
holder.test_price.setText(android.get(position).getTest_price());
holder.chkSelected.setChecked(android.get(position).isSelected());
holder.chkSelected.setTag(android.get(position));
holder.chkSelected.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
TestListModel contact = (TestListModel) cb.getTag();
contact.setSelected(cb.isChecked());
android.get(position).setSelected(cb.isChecked());
Toast.makeText(
v.getContext(),
"Clicked on Checkbox: " + cb.getText() + " is " + cb.isChecked(), Toast.LENGTH_LONG).show();
}
});
}
#Override
public int getItemCount() {
return android.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView test_name;
private TextView test_price;
public CheckBox chkSelected;
public TestListModel testLists;
public ViewHolder(View itemView) {
super(itemView);
test_name = (TextView)itemView.findViewById(R.id.test_name);
test_price = (TextView)itemView.findViewById(R.id.price_name);
chkSelected = (CheckBox) itemView.findViewById(R.id.check_box);
}
}
// method to access in activity after updating selection
public List<TestListModel> getTestList() {
return android;
}
AmountCartModel.java
public class AmountCartModel {
private String testName;
private String testPrice;
private Integer serialNumber;
private Integer totalPrice;
public AmountCartModel() {
this.testName = testName;
this.testPrice = testPrice;
this.serialNumber = serialNumber;
this.totalPrice = totalPrice;
}
public String getTestName() {
return testName;
}
public void setTestName(String testName) {
this.testName = testName;
}
public String getTestPrice() {
return testPrice;
}
public void setTestPrice(String testPrice) {
this.testPrice = testPrice;
}
public Integer getSerialNumber() {
return serialNumber;
}
public void setSerialNumber(Integer serialNumber) {
this.serialNumber = serialNumber;
}
public Integer getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(Integer totalPrice) {
this.totalPrice = totalPrice;
}
}
AmountCartActivity.java
public class AmountCartActivity extends AppCompatActivity implements View.OnClickListener {
#BindView(R.id.total_price)
TextView totalPriceDisplay;
SharePreferenceManager<LoginModel> sharePreferenceManager;
private RecyclerView recyclerView;
List<AmountCartModel> mydataList ;
private MyAdapter madapter;
Bundle extras ;
String testName="";
String testPrice="";
String totalPrice= "";
int counting = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_amount_cart);
ButterKnife.bind(this);
sharePreferenceManager = new SharePreferenceManager<>(getApplicationContext());
showcenterid(sharePreferenceManager.getUserLoginData(LoginModel.class));
mydataList = new ArrayList<>();
/*
* Getting Values From BUNDLE
* */
extras = getIntent().getExtras();
if (extras != null) {
testName = extras.getString("test_name");
testPrice = extras.getString("test_price");
totalPrice = String.valueOf(extras.getInt("total_price"));
counting = extras.getInt("serialNumber");
//Just add your data in list
AmountCartModel mydata = new AmountCartModel(); // object of Model Class
mydata.setTestName(testName );
mydata.setTestPrice(testPrice);
mydata.setTotalPrice(Integer.valueOf(totalPrice));
mydata.setSerialNumber(counting);
mydataList.add(mydata);
//totalPriceDisplay.setText(totalPrice);
}
madapter=new MyAdapter(mydataList);
madapter.setMyDataList(mydataList);
recyclerView = (RecyclerView)findViewById(R.id.recyler_amount_cart);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(madapter);
RecyclerAdapter.java //RecyclerAdapter for AmountCart
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>
{
private List<AmountCartModel> context;
private List<AmountCartModel> myDataList;
public MyAdapter(List<AmountCartModel> context) {
this.context = context;
myDataList = new ArrayList<>();
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
// Replace with your layout
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.amount_cart_row, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// Set Your Data here to yout Layout Components..
// to get Amount
/* myDataList.get(position).getTestName();
myDataList.get(position).getTestPrice();*/
holder.testName.setText(myDataList.get(position).getTestName());
holder.testPrice.setText(myDataList.get(position).getTestPrice());
holder.textView2.setText(myDataList.get(position).getSerialNumber());
}
#Override
public int getItemCount() {
/*if (myDataList.size() != 0) {
// return Size of List if not empty!
return myDataList.size();
}
return 0;*/
return myDataList.size();
}
public void setMyDataList(List<AmountCartModel> myDataList) {
// getting list from Fragment.
this.myDataList = myDataList;
notifyDataSetChanged();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView testName,testPrice,textView2;
public ViewHolder(View itemView) {
super(itemView);
// itemView.findViewById
testName=itemView.findViewById(R.id.test_name_one);
testPrice=itemView.findViewById(R.id.test_price);
textView2=itemView.findViewById(R.id.textView2);
}
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
startActivity(new
Intent(AmountCartActivity.this,HealthServicesActivity.class));
finish();
}
}
This is my code.
Here I am taking HealthActivity and in this class by using recycler view I have displayed testList in recycler view. I am passing testList whichever I am selecting through checkbox to AmountCartActivity of recycler View, And, I am calculating total amount of the selected testList and I am getting the result and that result I am passing to the AmountCart Activity through bundle and I am getting correct result in bundle, but, when I am trying to display total amount in a textView its showing me nothing.
And, my second problem is,
I am trying to display serial number to to my AmountCartActivity of recycler view whichever I am selecting from previous HealthCartActivity using checkbox. And, I have implemented some code but I am not getting how to solve it. please help me.
For Issue#1
Data should be passed onto the Adapter through constructor. The issue could simply be adding another parameter to the constructor:
public MyAdapter(List<AmountCartModel> context, List<AmountCartModel> myDataList) {
this.context = context;
myDataList = this.myDataList;
}
Or,
To add selection support to a RecyclerView instance:
Determine which selection key type to use, then build a ItemKeyProvider.
Implement ItemDetailsLookup: it enables the selection library to access information about RecyclerView items given a MotionEvent.
Update item Views in RecyclerView to reflect that the user has selected or unselected it.
The selection library does not provide a default visual decoration for the selected items. You must provide this when you implement onBindViewHolder() like,
In onBindViewHolder(), call setActivated() (not setSelected()) on the View object with true or false (depending on if the item is selected).
Update the styling of the view to represent the activated status.
For Issue #2
Try using passing data through intents.
The easiest way to do this would be to pass the serial num to the activity in the Intent you're using to start the activity:
Intent intent = new Intent(getBaseContext(), HealthServicesActivity.class);
intent.putExtra("EXTRA_SERIAL_NUM", serialNum);
startActivity(intent);
Access that intent on next activity
String sessionId= getIntent().getStringExtra("EXTRA_SERIAL_NUM");

Deleting all items in a page one by one in Android recyclerview does not load the next set of data

I have implemented recyclerview and it loads 10 tasks at a time. Once every task is completed, I am removing the task with a completed button. It loads the 11th item if I scroll to the bottom at one condition there has to be atleast one uncompleted task present on the page. If I clear all 10 items it just shows me loading animation and nothing happens. I have to close the app and open again to load the tasks again.
I have implemented a PaginationActivity, PaginationAdapter and scroll listener for the page. It loads data from a local database whenever you have reached the end of the page and you have got more tasks to load.
PaginationActivity.java
public class PaginationActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
PaginationAdapter adapter;
LinearLayoutManager linearLayoutManager;
public static ArrayList<String> reasonsdata = new ArrayList<String>();
public static String rslt="";
public static String[] reasons;
public static boolean chk = true;
public static String payTypeSelected;
public static String reasonSelected;
public static HashMap<String, EditText> drivernotesMap = new HashMap<String, EditText>();
public static HashMap<String, EditText> paynoteMap = new HashMap<String, EditText>();
public static HashMap<String, String> paytypeMap = new HashMap<String, String>();
RecyclerView rv;
ProgressBar progressBar;
private static final int PAGE_START = 0;
private boolean isLoading = false;
private boolean isLastPage = false;
private int TOTAL_PAGES;
private int currentPage = PAGE_START;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pagination_main);
fillspinner();
rv = (RecyclerView) findViewById(R.id.main_recycler);
progressBar = (ProgressBar) findViewById(R.id.main_progress);
adapter = new PaginationAdapter(this);
linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
rv.setLayoutManager(linearLayoutManager);
rv.setItemAnimator(new DefaultItemAnimator());
rv.setAdapter(adapter);
rv.addOnScrollListener(new PaginationScrollListener(linearLayoutManager) {
#Override
protected void loadMoreItems() {
isLoading = true;
currentPage += 1;
// mocking network delay for API call
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
loadNextPage();
}
}, 1000);
}
#Override
public int getTotalPageCount() {
return TOTAL_PAGES;
}
#Override
public boolean isLastPage() {
return isLastPage;
}
#Override
public boolean isLoading() {
return isLoading;
}
});
// mocking network delay for API call
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
loadFirstPage();
}
}, 1000);
}
private void fillspinner() {
reasonsdata.clear();
try
{
rslt="START";
CallReasons cr = new CallReasons();
cr.join();
cr.start();
while(rslt=="START") {
try {
Thread.sleep(10);
}catch(Exception ex) {
}
}
}
catch (Exception ex) {
ex.printStackTrace();
}
if(rslt == "Success"){
reasonsdata.add("<--- Select Reason --->");
for(int i =0; i< reasons.length;i++){
reasonsdata.add(reasons[i]);
}
}
}
public void loadFirstPage() {
Log.d(TAG, "loadFirstPage: ");
TOTAL_PAGES = Run.getTotalPages();
//List<Run> runs = Run.createRuns(adapter.getItemCount());
List<Run> runs = Run.createRuns(adapter.getMaxID());
progressBar.setVisibility(View.GONE);
adapter.addAll(runs);
if (currentPage <= TOTAL_PAGES) adapter.addLoadingFooter();
else isLastPage = true;
}
public void loadNextPage() {
Log.d(TAG, "loadNextPage: " + currentPage);
//List<Run> runs = Run.createRuns(adapter.getItemCount());
List<Run> runs = Run.createRuns(adapter.getMaxID());
adapter.removeLoadingFooter();
isLoading = false;
adapter.addAll(runs);
if (currentPage != TOTAL_PAGES) adapter.addLoadingFooter();
else isLastPage = true;
}
}
PaginationAdapter.java
public class PaginationAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int ITEM = 0;
private static final int LOADING = 1;
private List<Run> runs = new ArrayList<>();
private Context context;
private boolean isLoadingAdded = false;
private String cash = "CASH";
private String cheque = "CHEQUE";
SQLiteDatabase db;
//PaginationActivity func_call;
public PaginationAdapter(Context context) {
this.context = context;
runs = new ArrayList<>();
//func_call = new PaginationActivity();
}
public List<Run> getRuns() {
return runs;
}
public void setRuns(List<Run> runs) {
this.runs = runs;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case ITEM:
viewHolder = getViewHolder(parent, inflater);
break;
case LOADING:
View v2 = inflater.inflate(R.layout.item_progress, parent, false);
viewHolder = new LoadingVH(v2);
//viewHolder = getViewHolder(parent, inflater);
//func_call.loadNextPage();
break;
}
return viewHolder;
}
#NonNull
private RecyclerView.ViewHolder getViewHolder(ViewGroup parent, LayoutInflater inflater) {
RecyclerView.ViewHolder viewHolder;
View v1 = inflater.inflate(R.layout.activity_main, parent, false);
viewHolder = new RunVH(v1);
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final Run run = runs.get(position);
switch (getItemViewType(position)) {
case ITEM:
final RunVH runVH = (RunVH) holder;
//adding text areas to show data
//Completed task button
runVH.btnSave.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Toast.makeText(context, "Mark as Completed", Toast.LENGTH_LONG).show();
remove(run);
}
}
} catch (Exception ex) {
//pbbar.setVisibility(View.GONE);
ex.printStackTrace();
}
}
});
break;
case LOADING:
break;
}
}
#Override
public int getItemCount() {
return runs == null ? 0 : runs.size();
}
//#Override
public int getMaxID() {
if(runs == null || runs.size() == 0){
return 0;
}else{
Run test = runs.get(runs.size()-2);
int maxid = (int) test.getProperty(0);
return maxid;
}
}
#Override
public int getItemViewType(int position) {
return (position == runs.size() - 1 && isLoadingAdded) ? LOADING : ITEM;
}
public void add(Run run) {
runs.add(run);
notifyItemInserted(runs.size() - 1);
}
public void addAll(List<Run> runList) {
for (Run run : runList) {
add(run);
}
}
public void remove(Run run) {
int position = runs.indexOf(run);
if (position > -1) {
runs.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, runs.size());
}
/*if(runs.size() < 0){
clear();
func_call.loadNextPage();
}*/
}
public void clear() {
isLoadingAdded = false;
while (getItemCount() > 0) {
remove(getItem(0));
}
}
public boolean isEmpty() {
return getItemCount() == 0;
}
public void addLoadingFooter() {
isLoadingAdded = true;
add(new Run());
}
public void removeLoadingFooter() {
isLoadingAdded = false;
int position = runs.size() - 1;
Run item = getItem(position);
if (item != null) {
runs.remove(position);
notifyItemRemoved(position);
}
}
public Run getItem(int position) {
return runs.get(position);
}
protected class RunVH extends RecyclerView.ViewHolder {
private TextView textEsky;
private TextView textAdjusted;
private TextView textAddress;
private TextView textNew;
private TextView textTrusted;
private TextView textName;
private TextView textMobile;
private TextView textHome;
private TextView textWork;
private TextView payType;
private EditText textPayNote;
private EditText textDeliveryInst;
private EditText textDriverNotes;
private final Spinner reasons;
private RadioGroup rg;
private Button btnSave;
private CheckBox IsDriverData;
public RunVH(View itemView) {
super(itemView);
textEsky = (TextView) itemView.findViewById(R.id.idEsky);
textAdjusted = (TextView) itemView.findViewById(R.id.idAdjusted);
textAddress = (TextView) itemView.findViewById(R.id.idAddress);
textNew = (TextView) itemView.findViewById(R.id.idNew);
textTrusted = (TextView) itemView.findViewById(R.id.idTrusted);
textName = (TextView) itemView.findViewById(R.id.idName);
textMobile = (TextView) itemView.findViewById(R.id.idMobile);
textHome = (TextView) itemView.findViewById(R.id.idHome);
textWork = (TextView) itemView.findViewById(R.id.idWork);
payType = (TextView) itemView.findViewById(R.id.idPayType);
textPayNote = (EditText) itemView.findViewById(R.id.idPayNoteText);
textDeliveryInst = (EditText) itemView.findViewById(R.id.idDeliInsText);
textDriverNotes = (EditText) itemView.findViewById(R.id.idDriverNotesText);
IsDriverData = (CheckBox) itemView.findViewById(R.id.idCheckBox);
reasons = (Spinner) itemView.findViewById(R.id.idReason);
rg = (RadioGroup) itemView.findViewById(R.id.Radiogroup);
btnSave = (Button) itemView.findViewById(R.id.button);
}
}
protected class LoadingVH extends RecyclerView.ViewHolder {
public LoadingVH(View itemView) {
super(itemView);
}
}
}
PaginationScrollListener.java
public abstract class PaginationScrollListener extends RecyclerView.OnScrollListener {
LinearLayoutManager layoutManager;
public PaginationScrollListener(LinearLayoutManager layoutManager) {
this.layoutManager = layoutManager;
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = layoutManager.getChildCount();
int totalItemCount = layoutManager.getItemCount();
int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
if (!isLoading() && !isLastPage()) {
if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount
&& firstVisibleItemPosition >= 0) {
loadMoreItems();
}
}
}
protected abstract void loadMoreItems();
public abstract int getTotalPageCount();
public abstract boolean isLastPage();
public abstract boolean isLoading();
}
I could be wrong, but it looks to me like the only time you call loadNextPage() is when the RecyclerView gets a scroll event. Removing ViewHolders doesn't cause scroll events iirc.
If you register an AdapterDataObserver on the PaginationAdapter, you can listen in on removal/add events and trigger loads when there aren't any tasks left. You could probably do the same thing with some small changes to that commented-out code in remove(Run):
if (runs.isEmpty()) {
func_call.loadNextPage();
}
EDIT:
Btw, you see where you called adapter = new PaginationAdapter(this); in the PaginationActivity.onCreate method? The this here is your PaginationActivity, which means you can assign it to a PaginationAdapter field like so:
/**
* #param context the activity this adapter will appear in
*/
public PaginationAdapter(Context context) {
this.context = context;
runs = new ArrayList<>();
func_call = (PaginationActivity)context;
}
That should be enough to prevent crashes. For better separation of concerns, you'll probably want to switch over to AdapterDataObserver-based logic (I think this is called the open/closed principle? Maybe?).

How to instantiate interface from asynctask inside fragment

I have an Interface implemented in ProductListAdapter class which is a list adapter. Items in this list have three input fields. to keep track of those values I have implemented a class MyCustomEditTextListener which extends a TextWatcher class. This class simply create array list of edited data. I want to get reference to array list every time it changes from fragment which contains list view. For that I have implemented DataChangedListener
ProductListAdapter.java
public class ProductListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private LayoutInflater inflater;
private ArrayList<Products> listData;
private ArrayList<Products> editedData;
private Context context;
private DataChangedListener dataChangedListener;
private static final int ITEM = 0;
private static final int LOADING = 1;
private static final int QUANTITY = 5;
private static final int FREE_QUANTITY = 10;
private static final int DISCOUNT = 15;
public ProductListAdapter(ArrayList<Products> listData, ArrayList<Products> editedData, Context context) {
this.listData = listData;
this.context = context;
this.editedData = editedData;
inflater = LayoutInflater.from(this.context);
}
public void updateData(ArrayList<Products> data) {
this.listData = data;
notifyDataSetChanged();
}
public void setDataChangedListener(DataChangedListener listener) {
this.dataChangedListener = listener;
}
#Override
public int getItemViewType(int position) {
return listData.get(position) == null ? LOADING : ITEM;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
switch (viewType) {
case ITEM:
viewHolder = getViewHolder(parent, inflater);
break;
case LOADING:
View v2 = inflater.inflate(R.layout.list_footer, parent, false);
viewHolder = new LoadingVH(v2);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Products productObject = listData.get(position);
switch (getItemViewType(position)) {
case ITEM:
for(int i=0; i<editedData.size(); i++){
if(productObject.getProductId().equals(editedData.get(i).getProductId())){
productObject.setQuantity(editedData.get(i).getQuantity());
productObject.setFreeQuantity(editedData.get(i).getFreeQuantity());
productObject.setDiscount(editedData.get(i).getDiscount());
}
}
String productName = productObject.getProductName();
String quantityValue = productObject.getQuantity();
String freeQuantityValue = productObject.getFreeQuantity();
String discountValue = productObject.getDiscount();
String quantityInHand = productObject.getQuantityInHand();
String price = productObject.getWholeSalePrice();
ContentViewHolder movieVH = (ContentViewHolder) holder;
movieVH.productName.setText(productName);
movieVH.stock.setText(quantityInHand);
movieVH.price.setText("Rs."+price);
movieVH.quantityEditTextListener.updatePosition(movieVH.getLayoutPosition());
movieVH.quantity.setText(quantityValue);
movieVH.freeQuantityEditTextListener.updatePosition(movieVH.getLayoutPosition());
movieVH.freeQuantity.setText(freeQuantityValue);
movieVH.discountEditTextListener.updatePosition(movieVH.getLayoutPosition());
movieVH.discount.setText(discountValue);
movieVH.quantity.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
return false;
}
});
break;
case LOADING:
//Do nothing
break;
}
}
#Override
public int getItemCount() {
return listData == null ? 0 : listData.size();
}
#NonNull
private RecyclerView.ViewHolder getViewHolder(ViewGroup parent, LayoutInflater inflater) {
RecyclerView.ViewHolder viewHolder;
View view = inflater.inflate(R.layout.custom_product_list_item, parent, false);
viewHolder = new ContentViewHolder(view, new MyCustomEditTextListener()
, new MyCustomEditTextListener(), new MyCustomEditTextListener());
return viewHolder;
}
/**
* View holder for main container
*/
public class ContentViewHolder extends RecyclerView.ViewHolder{
private TextView productName;
private EditText quantity;
private EditText freeQuantity;
private EditText discount;
private TextView stock;
private TextView price;
private MyCustomEditTextListener quantityEditTextListener;
private MyCustomEditTextListener freeQuantityEditTextListener;
private MyCustomEditTextListener discountEditTextListener;
public ContentViewHolder(View itemView, MyCustomEditTextListener textListener
, MyCustomEditTextListener textListener2, MyCustomEditTextListener textListener3) {
super(itemView);
productName = (TextView) itemView.findViewById(R.id.product_name_data);
quantity = (EditText) itemView.findViewById(R.id.quantity_1_edit_text);
freeQuantity = (EditText) itemView.findViewById(R.id.quantity_2_edit_text);
discount = (EditText) itemView.findViewById(R.id.quantity_3_edit_text);
stock = (TextView) itemView.findViewById(R.id.quantity_in_hand_value);
price = (TextView) itemView.findViewById(R.id.price_value);
quantityEditTextListener = textListener;
quantityEditTextListener.setEditTextType(QUANTITY);
freeQuantityEditTextListener = textListener2;
freeQuantityEditTextListener.setEditTextType(FREE_QUANTITY);
discountEditTextListener = textListener3;
discountEditTextListener.setEditTextType(DISCOUNT);
this.quantity.addTextChangedListener(quantityEditTextListener);
this.freeQuantity.addTextChangedListener(freeQuantityEditTextListener);
this.discount.addTextChangedListener(discountEditTextListener);
}
}
/**
* View holder to display loading list item
*/
protected class LoadingVH extends RecyclerView.ViewHolder {
public LoadingVH(View itemView) {
super(itemView);
}
}
/**
* textWatcher for to keep track of changed data.
*/
private class MyCustomEditTextListener implements TextWatcher {
private int position;
private int type;
public void updatePosition(int position) {
this.position = position;
}
public void setEditTextType(int type) {
this.type = type;
}
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
// no op
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
if (type == QUANTITY) {
listData.get(position).setQuantity(charSequence.toString());
} else if (type == FREE_QUANTITY) {
listData.get(position).setFreeQuantity(charSequence.toString());
} else if (type == DISCOUNT) {
listData.get(position).setDiscount(charSequence.toString());
}
}
#Override
public void afterTextChanged(Editable s) {
boolean matchFound = false;
if(s.toString().length()>0){
for (int i=0;i<editedData.size();i++){
if(editedData.get(i).getProductId()
.equals(listData.get(position).getProductId())){
matchFound = true;
if (type == QUANTITY) {
editedData.get(i).setQuantity(s.toString());
} else if (type == FREE_QUANTITY) {
editedData.get(i).setFreeQuantity(s.toString());
} else if (type == DISCOUNT) {
editedData.get(i).setDiscount(s.toString());
}
}
}
if(!matchFound){
editedData.add(listData.get(position));
}
if(dataChangedListener!=null){
dataChangedListener.onDataChanged(editedData);
}
}
}
}
public interface DataChangedListener{
void onDataChanged(ArrayList<Products> editedData);
}
In my OrderEditFragment i'm trying to implement that interface to do necessary calculations.
OrderEditFragment.java
public class OrderEditFragment extends Fragment implements ProductListAdapter.DataChangedListener {
private LinearLayoutManager layoutManager;
private RecyclerView productRecyclerView;
private static ProductListAdapter productListAdapter;
private String employeeId;
private static ArrayList<Products> editedData;
private static ArrayList<Products> productsData;
private SharedPreferences sharedpreferences;
private final static OkHttpClient client = new OkHttpClient();
public OrderEditFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View inflate = inflater.inflate(R.layout.fragment_order_edit, container, false);
initComponents(inflate);
return inflate;
}
private void initComponents(View view) {
productRecyclerView = (RecyclerView) view.findViewById(R.id.product_edit_recycler_view);
progressView = (CircularProgressView) view.findViewById(R.id.progress_view);
layoutManager = new LinearLayoutManager(getContext());
sharedpreferences = getActivity().getSharedPreferences("dgFashionPref", Context.MODE_PRIVATE);
employeeId = sharedpreferences.getString("employee_id","");
productsData = new ArrayList<>();
editedData = new ArrayList<>();
isLoading = false;
isLastPage = false;
isFirstLoad = true;
isSearch = false;
new GetProductListGetRequest(getContext(), productRecyclerView, layoutManager)
.execute(RestConnection.PRODUCT_LIST_GET
+ RestConnection.CUSTOMER_ID_FOR_NAME + employeeId);
}
#Override
public void onDataChanged(ArrayList<Products> editedData) {
Log.d(TAG,editedData.toString());
}
/**
* AsyncTask class which handel the GET request to get product list
**/
public static class GetProductListGetRequest extends AsyncTask<String, Void, String>{
private WeakReference<Context> ActivityWeakReference;
private WeakReference<RecyclerView> recyclerViewWeakReference;
private WeakReference<RecyclerView.LayoutManager> layoutManagerWeakReference;
public GetProductListGetRequest(Context activity, RecyclerView recyclerView
, RecyclerView.LayoutManager layoutManager) {
ActivityWeakReference = new WeakReference<>(activity);
recyclerViewWeakReference = new WeakReference<>(recyclerView);
layoutManagerWeakReference = new WeakReference<>(layoutManager);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String urlEndPoint = params[0];
Request request = new Request.Builder()
.url(RestConnection.API_BASE + urlEndPoint)
.build();
try {
Response response = client.newCall(request).execute();
return response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String response) {
if( productsData.size()>0){
productsData.remove(productsData.size() - 1);
}
JSONArray responseBody;
try {
if (response != null && ActivityWeakReference.get() != null) {
responseBody = new JSONArray(response);
for (int i = 0; i < responseBody.length(); i++) {
JSONObject row = responseBody.getJSONObject(i);
String productId = row.getString("ProductID");
String productName = row.getString("Name");
String unit = row.getString("Unit");
String wholeSalePrice = row.getString("WSalePrice");
String packSize = row.getString("PackSize");
String retailPrice = row.getString("RetailPrice");
String costPrice = row.getString("CostPrice");
String qtyInHand = row.getString("QtyInHand");
Products productObj = new Products();
productObj.setProductName(productName);
productObj.setProductId(productId);
productObj.setUnit(unit);
productObj.setWholeSalePrice(wholeSalePrice);
productObj.setPackSize(packSize);
productObj.setRetailPrice(retailPrice);
productObj.setCostPrice(costPrice);
productObj.setQuantityInHand(qtyInHand);
productsData.add(productObj);
}
productListAdapter = new ProductListAdapter(productsData, editedData, ActivityWeakReference.get());
productListAdapter.setDataChangedListener(ActivityWeakReference.get());
recyclerViewWeakReference.get().setAdapter(productListAdapter);
recyclerViewWeakReference.get().setLayoutManager(layoutManagerWeakReference.get());
recyclerViewWeakReference.get().addItemDecoration(new RecyclerViewDivider(2));
} else {
Toast.makeText(ActivityWeakReference.get(), "Can't connect to the server", Toast.LENGTH_LONG).show();
}
} catch (JSONException e)
{
Log.d(TAG, "Get customer details onPostExecute :" + e.getLocalizedMessage());
}
}
}
/**
* A class that define space between list items
*/
private static class RecyclerViewDivider extends RecyclerView.ItemDecoration {
int space;
public RecyclerViewDivider(int space) {
this.space = space;
}
#Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.bottom = space;
if (parent.getChildLayoutPosition(view) == 0) {
outRect.top = space;
}
}
}
}
As you can see I'm trying to instantiate interface inside AsyncTask class soon after created productListAdapter object by calling setDataChangedListener(DataChangedListener listener); method. But it did not take ActivityWeakReference.get() as a valid parameter. I have done slimier thing before with list adapter to bring custom created onListItemClick event to activity. In those cases ActivityWeakReference.get() works fine. I think this is happening because I'm in a fragment, But I can't figure out which object I should pass. I need to create Adapter inside AsyncTask because i have implemented pagination for list view. I remove those codes to make this post short. Please help.
Found the solution. You need to pass fragment object to interface not the activity.
Here's my fragment class now.
/**
* AsyncTask class which handel the GET request to get product list
**/
public static class GetProductListGetRequest extends AsyncTask<String, Void, String>{
private WeakReference<OrderEditFragment> fragmentWeakReference;
private WeakReference<RecyclerView> recyclerViewWeakReference;
private WeakReference<RecyclerView.LayoutManager> layoutManagerWeakReference;
public GetProductListGetRequest(OrderEditFragment fragment, RecyclerView recyclerView
, RecyclerView.LayoutManager layoutManager) {
fragmentWeakReference = new WeakReference<>(fragment);
recyclerViewWeakReference = new WeakReference<>(recyclerView);
layoutManagerWeakReference = new WeakReference<>(layoutManager);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String urlEndPoint = params[0];
Request request = new Request.Builder()
.url(RestConnection.API_BASE + urlEndPoint)
.build();
//Log.d(TAG,RestConnection.API_BASE + urlEndPoint);
try {
Response response = client.newCall(request).execute();
return response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String response) {
if( productsData.size()>0){
productsData.remove(productsData.size() - 1);
}
JSONArray responseBody;
//Log.d(TAG,response);
try {
if (response != null && fragmentWeakReference.get() != null) {
responseBody = new JSONArray(response);
for (int i = 0; i < responseBody.length(); i++) {
JSONObject row = responseBody.getJSONObject(i);
String productId = row.getString("ProductID");
String productName = row.getString("Name");
String unit = row.getString("Unit");
String wholeSalePrice = row.getString("WSalePrice");
String packSize = row.getString("PackSize");
String retailPrice = row.getString("RetailPrice");
String costPrice = row.getString("CostPrice");
String qtyInHand = row.getString("QtyInHand");
Products productObj = new Products();
productObj.setProductName(productName);
productObj.setProductId(productId);
productObj.setUnit(unit);
productObj.setWholeSalePrice(wholeSalePrice);
productObj.setPackSize(packSize);
productObj.setRetailPrice(retailPrice);
productObj.setCostPrice(costPrice);
productObj.setQuantityInHand(qtyInHand);
productsData.add(productObj);
}
/** if lower limit and upper limit change, change responseBody.length()<10 respectively **/
if (responseBody.length() == 0 || responseBody.length() < 10) {
isLastPage = true;
}
if (isFirstLoad) {
progressView.setVisibility(View.GONE);
recyclerViewWeakReference.get().setVisibility(View.VISIBLE);
productListAdapter = new ProductListAdapter(productsData, editedData, fragmentWeakReference.get().getContext());
productListAdapter.setDataChangedListener(fragmentWeakReference.get());
recyclerViewWeakReference.get().setAdapter(productListAdapter);
recyclerViewWeakReference.get().setLayoutManager(layoutManagerWeakReference.get());
recyclerViewWeakReference.get().addItemDecoration(new RecyclerViewDivider(2));
isFirstLoad = false;
} else {
productListAdapter.updateData(productsData);
isLoading = false;
}
} else {
Toast.makeText(fragmentWeakReference.get().getContext(), "Can't connect to the server", Toast.LENGTH_LONG).show();
}
} catch (JSONException e)
{
Log.d(TAG, "Get customer details onPostExecute :" + e.getLocalizedMessage());
}
}
}
And create AsyncTask object like bellow.
new GetProductListGetRequest(this, productRecyclerView, layoutManager)
.execute(RestConnection.PRODUCT_LIST_GET
+ RestConnection.CUSTOMER_ID_FOR_NAME + employeeId);

RecyclerView notifyDatasetChanged not working

I have a RecyclerView inside a Fragment within Activity. I need to refresh my RecyclerView from Activity. I added a method inside Fragment which called notifyDatasetChanged to refresh RecyclerView. But notifyDatasetChanged didn't work.
Here is my Fragment.
public class CategoryFragment extends Fragment{
private RecyclerView recyclerView;
private EventsAdapter adapter;
static Context context = null;
private List<Category> categories;
private List<Item> allItems = new ArrayList();
private ReminderDatabase dbHandler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(!checkDatabase()){
copyDatabase();
}
context = getActivity();
dbHandler = new ReminderDatabase(context);
fillAllItems();
}
public void fillAllItems(){
categories = dbHandler.getAllCategory();
for(int i=0;i<categories.size();i++){
Category category = categories.get(i);
Item categoryItem = new Item(category.getTitle(),category.getColor(),Category.CATEGORY_TYPE);
allItems.add(categoryItem);
List<Event> events = dbHandler.getEventsByCategory(category.getTitle());
for(int j=0;j<events.size();j++){
Event e = events.get(j);
Item eventItem = new Item(e.getId(),e.getTitle(),e.getDescription(),e.getPlace(),e.getCategory(),e.getTime(),e.getDate(),categoryItem.getColor(),e.isShow(),Event.EVENT_TYPE);
allItems.add(eventItem);
}
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.category_fragment, container, false);
recyclerView = (RecyclerView) v.findViewById(R.id.recyclerView);
adapter = new EventsAdapter(getContext(),allItems);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(adapter);
return v;
}
public boolean checkDatabase(){
String path = "/data/data/com.example.materialdesign.reminder/databases/";
String filename = "Remind";
File file = new File(path+filename);
Log.d("Database","File exists -> "+file.exists());
return file.exists();
}
public void copyDatabase(){
String path = "/data/data/com.example.materialdesign.reminder/databases/Remind";
ReminderDatabase dbHandler = new ReminderDatabase(getContext());
dbHandler.getWritableDatabase();
InputStream fin;
OutputStream fout;
byte[] bytes = new byte[1024];
try {
fin = getActivity().getAssets().open("Remind");
fout = new FileOutputStream(path);
int length=0;
while((length = fin.read(bytes))>0){
fout.write(bytes,0,length);
}
fout.flush();
fout.close();
fin.close();
Log.d("Database","successfully copied database");
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.d("Database","-Error" +e.getMessage());
} catch (IOException e) {
e.printStackTrace();
Log.d("Database","-Error" +e.getMessage());
}
}
#Override
public void onResume() {
super.onResume();
allItems.clear();
Log.d("TAG","onresume");
fillAllItems();
adapter.notifyDataSetChanged();
}
public void refresh(){
Log.d("c",allItems.size()+"");
allItems.clear();
fillAllItems();
Log.d("c",allItems.size()+"");
adapter.notifyDataSetChanged();
}
}
I called refresh method from MainActivity.
#Override
public void onInserted() {
fragment.refresh();
}
My Adapter is here.
public class EventsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private Context context;
private List<Item> allItems = new ArrayList();
private HideOrShowListener hideOrShowListener;
public static final int EVENT_TYPE = 1;
public static final int CATEGORY_TYPE = 0;
private int lastPosition;
private boolean flag = false;
public EventsAdapter(Context context,List<Item> allItems){
this.context = context;
hideOrShowListener =(HideOrShowListener) context;
this.allItems = allItems;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
switch (viewType){
case CATEGORY_TYPE:
view = LayoutInflater.from(context).inflate(R.layout.category_item,parent,false);
return new CategoryViewHolder(view);
case EVENT_TYPE:
view = LayoutInflater.from(context).inflate(R.layout.events_item,parent,false);
return new EventViewHolder(view);
}
return null;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final Item item = allItems.get(position);
switch (item.getType()){
case CATEGORY_TYPE:
((CategoryViewHolder)holder).tvCategoryTitle.setText(item.getTitle());
((GradientDrawable)(((CategoryViewHolder)holder).categoryColorIcon).getBackground()).setColor(Color.parseColor(item.getColor()));
((CategoryViewHolder)holder).imgAddEvent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
hideOrShowListener.setHideOrShow(item,false);
}
});
break;
case EVENT_TYPE:
String[] time = item.getTime().trim().split(":");
int hour = Integer.parseInt(time[0]);
((EventViewHolder)holder).tvEventName.setText(item.getTitle());
((EventViewHolder)holder).tvTime.setText(hour<12?hour+" : "+time[1] +" am" : hour-12+" : "+time[1] +" pm" );
((EventViewHolder)holder).tvPlace.setText(item.getPlace());
if(item.getDescription().length()==0) {
item.setDescription("No Detail");
}
((EventViewHolder)holder).tvDescription.setText(item.getDescription());
if(item.isShow()){
((EventViewHolder)holder).descriptionLayout.animate().alpha(1).setDuration(200).setInterpolator(new AccelerateInterpolator()).start();
((EventViewHolder)holder).descriptionLayout.setVisibility(View.VISIBLE);
((EventViewHolder)holder).descriptionLayout.setSelected(true);
((EventViewHolder)holder).tvEdit.setVisibility(View.VISIBLE);
((EventViewHolder)holder).eventContainer.setSelected(true);
}else{
((EventViewHolder)holder).descriptionLayout.setVisibility(View.GONE);
((EventViewHolder)holder).descriptionLayout.animate().alpha(0).setDuration(500).start();
((EventViewHolder)holder).descriptionLayout.setSelected(false);
((EventViewHolder)holder).eventContainer.setSelected(false);
((EventViewHolder)holder).tvEdit.setVisibility(View.INVISIBLE);
}
((EventViewHolder)holder).tvEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
hideOrShowListener.setHideOrShow(item,true);
}
});
break;
}
}
#Override
public int getItemCount() {
Log.d("c",allItems.size()+"");
return allItems.size();
}
#Override
public int getItemViewType(int position) {
if(allItems!=null){
return allItems.get(position).getType();
}
return 0;
}
public class CategoryViewHolder extends RecyclerView.ViewHolder{
private TextView tvCategoryTitle;
private View categoryColorIcon;
private ImageView imgAddEvent;
public CategoryViewHolder(View itemView) {
super(itemView);
tvCategoryTitle = (TextView) itemView.findViewById(R.id.tvCategoryTitle);
categoryColorIcon = itemView.findViewById(R.id.categoryColorIcon);
imgAddEvent = (ImageView) itemView.findViewById(R.id.addEvent);
}
}
public class EventViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private LinearLayout descriptionLayout;
private RelativeLayout eventContainer;
private TextView tvEventName,tvTime,tvPlace,tvDescription,tvEdit;
public EventViewHolder(View itemView) {
super(itemView);
descriptionLayout = (LinearLayout) itemView.findViewById(R.id.descriptionLayout);
eventContainer = (RelativeLayout) itemView.findViewById(R.id.eventContainer);
tvEventName = (TextView) itemView.findViewById(R.id.tvEventName);
tvTime = (TextView) itemView.findViewById(R.id.tvTime);
tvPlace = (TextView) itemView.findViewById(R.id.tvPlace);
tvDescription = (TextView) itemView.findViewById(R.id.tvDescription);
tvEdit = (TextView) itemView.findViewById(R.id.tvEdit);
eventContainer.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(flag){
allItems.get(lastPosition).setShow(false);
}
allItems.get(getAdapterPosition()).setShow(true);
flag = true;
lastPosition = getAdapterPosition();
notifyDataSetChanged();
}
}
public interface HideOrShowListener{
public void setHideOrShow(Item item , boolean isEdit);
}
}
But when I click home button and reenter my application, my RecyclerView refresh. It means that notifyDatasetChanged in onResume method works. But in my refresh method, it doesn't work. How can I do this?
Are you sure this method is being called :
#Override
public void onInserted() {
fragment.refresh();
}
Make sure that you've a correct instance of the fragment. Or you can simply user interface with the refresh() method and implement it in the fragment.

Categories

Resources