I have a recyclerview adapter that displays data in a list view which data were populated via cursor. I would like to extend further by setting a click to each list item and pass an intent of values to another Activity like a detail activity.
Adapter.class
public class RecyclerAdapter extends
RecyclerView.Adapter<RecyclerAdapter.Holder> {
/* ViewHolder for each insect item */
public class Holder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView friendlyName, scientificName, dangerLevel;
ImageView image;
public Holder(View itemView) {
super(itemView);
friendlyName = (TextView) itemView.findViewById(R.id.friendlyName);
scientificName = (TextView) itemView.findViewById(R.id.scientificName);
dangerLevel = (TextView) itemView.findViewById(R.id.text1);
}
#Override
public void onClick(View v) {
}
}
private Cursor mCursor;
private Context mContext;
public RecyclerAdapter(Context context, Cursor cursor) {
this.mContext = context;
this.mCursor = cursor;
}
#Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.bugs_list_item, parent, false);
return new Holder(view);
}
#Override
public void onBindViewHolder(Holder holder, int position) {
int insectname = mCursor.getColumnIndex(BugsContract.BugsEntry.COLUMN_FRIENDLYNAME);
int scienceName = mCursor.getColumnIndex(BugsContract.BugsEntry.COLUMN_SCIENTIFICNAME);
int id = mCursor.getColumnIndex(BugsContract.BugsEntry._ID);
int dangerlevel = mCursor.getColumnIndex(BugsContract.BugsEntry.COLUMN_DANGERLEVEL);
int insectImage = mCursor.getColumnIndex(BugsContract.BugsEntry.COLUMN_IMAGEASSET);
mCursor.moveToPosition(position);
String insectRName = mCursor.getString(insectname);
String scienceRName = mCursor.getString(scienceName);
String insectRImage = mCursor.getString(insectImage);
int dangerlevelInt = mCursor.getInt(dangerlevel);
String dangerString = "" + dangerlevelInt;
holder.dangerLevel.setText(dangerString);
holder.friendlyName.setText(insectRName);
holder.scientificName.setText(scienceRName);
}
private int getDangerColor(int danger) {
int priorityColor = 0;
int[] colorDangerarray = mContext.getResources().getIntArray(R.array.dangerColors);
switch(danger) {
case 1: priorityColor = ContextCompat.getColor(mContext, colorDangerarray[0]);
break;
case 2: priorityColor = ContextCompat.getColor(mContext, colorDangerarray[1]);
break;
case 3: priorityColor = ContextCompat.getColor(mContext, colorDangerarray[2]);
break;
default: break;
}
return priorityColor;
}
#Override
public int getItemCount() {
return mCursor.getCount();
}
/**
* Return the {#link Insect} represented by this item in the adapter.
*
* #param position Adapter item position.
*
* #return A new {#link Insect} filled with this position's attributes
*
* #throws IllegalArgumentException if position is out of the adapter's bounds.
*/
public Insect getItem(int position) {
if (position < 0 || position >= getItemCount()) {
throw new IllegalArgumentException("Item position is out of adapter's range");
} else if (mCursor.moveToPosition(position)) {
return new Insect(mCursor);
}
return null;
}
}
A model class that implements parceleable
public class Insect implements Parcelable {
private static final String TAG = Insect.class.getSimpleName();
//Common name
public int id;
public String name;
//Latin scientific name
public String scientificName;
//Classification order
public String classification;
//Path to image resource
public String imageAsset;
//1-10 scale danger to humans
public int dangerLevel;
/**
* Create a new Insect from discrete values
*/
public Insect(String name, String scientificName, String classification, String imageAsset, int dangerLevel) {
this.name = name;
this.scientificName = scientificName;
this.classification = classification;
this.imageAsset = imageAsset;
this.dangerLevel = dangerLevel;
}
/**
* Create a new Insect from a database Cursor
*/
public Insect(Cursor cursor) {
//TODO: Create a new insect from cursor
this.name = cursor.getString(cursor.getColumnIndex(BugsContract.BugsEntry.COLUMN_FRIENDLYNAME));
this.scientificName = cursor.getString(cursor.getColumnIndex(BugsContract.BugsEntry.COLUMN_SCIENTIFICNAME));
this.classification = cursor.getString(cursor.getColumnIndex(BugsContract.BugsEntry.COLUMN_CLASSIFICATION));
this.imageAsset = cursor.getString(cursor.getColumnIndex(BugsContract.BugsEntry.COLUMN_IMAGEASSET));
this.dangerLevel = Integer.parseInt(cursor.getString(cursor.getColumnIndex(BugsContract.BugsEntry.COLUMN_DANGERLEVEL)));
}
public Insect() {
}
/**
* Create a new Insect from a data Parcel
*/
protected Insect(Parcel in) {
this.name = in.readString();
this.scientificName = in.readString();
this.classification = in.readString();
this.imageAsset = in.readString();
this.dangerLevel = in.readInt();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(scientificName);
dest.writeString(classification);
dest.writeString(imageAsset);
dest.writeInt(dangerLevel);
}
#Override
public int describeContents() {
return 0;
}
public static final Creator<Insect> CREATOR = new Creator<Insect>() {
#Override
public Insect createFromParcel(Parcel in) {
return new Insect(in);
}
#Override
public Insect[] newArray(int size) {
return new Insect[size];
}
};
}
I would like to know how to declare an intent that houses the data to another activity and how to get data from the intent in the next activity
As long as you've implemented parcelable on your model class you can easily pass your object around like you usually would passing primitive data via putExtra() method.
For the sender activity:
Intent receiverIntent = new Intent(this, Receiver.class);
receiverIntent.putExtra("key", ParcelableObject);
startActivity(receiverIntent);
As for the receiver class, you just make an intent object to get the parcelableExtra in the onCreate() method.
Intent i = getIntent();
ParcelableClass parcelableObject;
parcelableObject = i.getParcelableExtra("key");
voila, that should do.
Related
I would like to update panel wise items in inner adapter item android recyclerview. When we pass the data dynamically.Data displaying is working fine. When we go to update the inner adapter item, it's not getting updated. But last item was getting update fine.
Activity.
public class PannelCreation extends AppCompatActivity {
RecyclerView userPanelRecycler;
List<String> roomPanels = new ArrayList<>();
List<JSONObject> roomItemObject = new ArrayList<JSONObject>();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pannel_creation);
userPanelRecycler = findViewById(R.id.user_panel_recycler);
for(int i=0; i<=5;i++){
roomPanels.add("Panels "+i)
}
PanelAdapter panelAdapter = new PanelAdapter(getApplicationContext(),roomPanels);
userPanelRecycler.setLayoutManager(new LinearLayoutManager(this));
userPanelRecycler.setHasFixedSize(true);
userPanelRecycler.setAdapter(panelAdapter);
}
}
// OuterAdapter
class PanelAdapter extends RecyclerView.Adapter<PanelAdapter.ViewHolder>{
Context context;
List<String> roomPanelList;
RecyclerView.RecycledViewPool recycledViewPool;
List<ItemData> itemDataList = new ArrayList<>();
public PanelAdapter(Context context, List<String> roomPanels) {
this.context = context;
this.roomPanelList = roomPanels;
recycledViewPool = new RecyclerView.RecycledViewPool();
}
#NonNull
#Override
public PanelAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.panel_wise_layout,parent,false);
ViewHolder viewHolder = new ViewHolder(view);
viewHolder.itemsRecycler.setRecycledViewPool(recycledViewPool);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull PanelAdapter.ViewHolder holder, int position) {
holder.userPanelName.setText(roomPanelList.get(position));
String cur_panelName = roomPanelList.get(position);
itemsAdapter = new ItemsAdapter(context);
holder.itemsRecycler.setLayoutManager(new GridLayoutManager(context,3));
holder. itemsRecycler.setHasFixedSize(true);
holder.itemsRecycler.setAdapter(itemsAdapter);
holder.itemsRecycler.setNestedScrollingEnabled(false);
try {
roomItemObject.clear();
JSONArray metaArray = new JSONArray(metaData);
int count = 0;
for(int i = 0;i<metaArray.length();i++){
JSONObject object = metaArray.getJSONObject(i);
String name = object.getString("name");
String[] rNum = name.split("_");
if(rNum[0].equalsIgnoreCase(roomNumber)){
roomItemObject.add(object);
}
count = count+1;
}
if(count == metaArray.length()){
int count1 = 0;
itemDataList.clear();
for(int i =0; i < roomItemObject.size();i++){
JSONObject itemObject1 = roomItemObject.get(i);
String groupNames = itemObject1.getString("groupNames");
String types = itemObject1.getString("type");
String metaValue = itemObject1.getString("metadata");
JSONObject panelObject = new JSONObject(metaValue);
String panel_name = panelObject.getString("panelName");
JSONObject valueObject = new JSONObject(panel_name);
String value = valueObject.getString("value");
if(value.equalsIgnoreCase(cur_panelName)){
String labels = itemObject1.getString("label");
String names = itemObject1.getString("name");
String state = itemObject1.getString("state");
String groupName = itemObject1.getString("groupNames");
String tags = itemObject1.getString("tags");
ItemData itemData = new ItemData();
itemData.setLabelName(labels);
itemData.setState(state);
itemData.setItemName(names);
itemData.setTags(tags);
itemData.setTypes(types);
itemData.setGroup(groupName);
itemDataList.add(itemData);
itemsAdapter.addItems(itemDataList);
itemsAdapter.notifyDataSetChanged();
}
}
}
}catch (JSONException e){
e.printStackTrace();
}
}
#Override
public int getItemCount() {
return roomPanelList.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
public class ViewHolder extends RecyclerView.ViewHolder{
RecyclerView itemsRecycler;
TextView userPanelName;
Button deletePanel;
public ViewHolder(#NonNull View itemView) {
super(itemView);
itemsRecycler = itemView.findViewById(R.id.panel_item_recycler);
userPanelName = itemView.findViewById(R.id.test_panel_name);
deletePanel = itemView.findViewById(R.id.delete_panel);
}
}
}
//Inner Adapter
class ItemsAdapter extends RecyclerView.Adapter<ItemsAdapter.ItemHolder>{
Context mContext;
List<ItemData> innerItemDataList = new ArrayList<>();
List<JSONObject> itemObjectList = new ArrayList<JSONObject>();
List<JSONObject> recObjectList = new ArrayList<>();
ItemData itemData;
public ItemsAdapter(Context context) {
this.mContext = context;
this.itemData = new ItemData();
}
public void addItems(List<ItemData> itemData){
this.innerItemDataList.clear();
this.innerItemDataList.addAll(itemData);
notifyDataSetChanged();
}
#NonNull
#Override
public ItemsAdapter.ItemHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(mContext).inflate(R.layout.panel_wise_item,parent,false);
return new ItemHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull ItemHolder holder, int position) {
itemData = innerItemDataList.get(position);
if(itemData != null){
holder.itemNames.setText(itemData.getLabelName());
}
#Override
public int getItemCount() {
return innerItemDataList.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
public class ItemHolder extends RecyclerView.ViewHolder {
TextView itemNames;
LinearLayout itemLayout;
ImageView itemImg;
public ItemHolder(#NonNull View itemView) {
super(itemView);
itemNames = itemView.findViewById(R.id.panel_item_name);
itemLayout = itemView.findViewById(R.id.panel_light_linear);
itemImg = itemView.findViewById(R.id.panel_item_img);
}
}
public void updateItem(String itemName,String state){
for(int j=0;j<innerItemDataList.size();j++){
if(itemName.equalsIgnoreCase(innerItemDataList.get(j).getItemName())){
innerItemDataList.get(j).setState(state);
notifyDataSetChanged();
}
}
}
}
//Inner adapter data model class
public class ItemData {
String labelName;
String itemName;
String state;
String group;
String tags;
String types;
public String getTypes() {
return types;
}
public void setTypes(String types) {
this.types = types;
}
public String getTags() {
return tags;
}
public void setTags(String tags) {
this.tags = tags;
}
public String getLabelName() {
return labelName;
}
public void setLabelName(String labelName) {
this.labelName = labelName;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
}
How to update specific item in inner adapter android nested recycler view.Can anyone guide me how to deal with update specific item. One more thing have observed inner adapter returns last position of array list only. Items are updating fine in last position of array list. When trying to updating the rest of position array list items, not getting updated.
Thanks in Advance.
Amar.
In outer adapter when ever data changes need to notify. Try this code
panelAdapter.notifyDataSetChanged();
I'm facing a bug while displaying some data through ListView with ArrayAdapter.
I have Order instances in my data defined by its ID.
The ListView displays it through a TextView with the ID.
The problem is that the first (and always the first) instance has its ID written 3 times.
ex:
Order n°111
Order n°2
Order n°3
It's not my first experience with ListViews and adapters and I've never had such a disagreement.
public class OrderAdapter extends ArrayAdapter<Order> {
public OrderAdapter(Context context, ArrayList<Order> orders) {
super(context, 0, orders);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Order order = getItem(position);
if(convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.order, parent, false);
}
TextView orderCheckedTextView = (TextView)convertView.findViewById(R.id.orderCheckedTextView);
System.out.println("###"+order.getId());
orderCheckedTextView.setText(orderCheckedTextView.getText()+Integer.toString(order.getId()));
return convertView;
}}
Here the print returns:
###1 ###1 ###1 ###2
Then I create 3 Orders add it to the data set and set the adapter to the listView:
Order order1 = new Order(Type.LIVRAISON,State.PREPARATION, PaymentType.CB, articleList, null);
Order order2 = new Order(Type.EMPORTE,State.PREPARATION, PaymentType.TICKET, articleList, null);
Order order3 = new Order(Type.EMPORTE,State.PREPARATION, PaymentType.TICKET, articleList, null);
parentActivity.model.getOrderlist().addOrder(order1);
parentActivity.model.getOrderlist().addOrder(order2);
parentActivity.model.getOrderlist().addOrder(order3);
this.inProgressOrderAdapter = new OrderAdapter(parentActivity.getApplicationContext(), parentActivity.model.getOrderlist().getInProgressOrderList());
final ListView inProgressOrderListView = (ListView)parentActivity.findViewById(R.id.inProgressOrderListView);
inProgressOrderListView.setAdapter(inProgressOrderAdapter);
public class Order {
private OrderList orderList= null;
private static int staticID = 0;
private int id = 0;
private Type type = null;
private PaymentType paymentType = null;
private State state = null;
private Date time = null;
private ArrayList<Object> articleList = new ArrayList<>();
private double totalPrice = 0;
private Deliver deliver = null;
public Order(Type type, State state, PaymentType paymentType, ArrayList<Object> articleList, Deliver deliver) {
staticID++;
this.id = staticID;
this.type = type;
this.state = state;
this.paymentType = paymentType;
this.articleList = articleList;
this.deliver = deliver;
for(Object article:articleList){
if(article instanceof Article){
totalPrice += ((Article)article).getPrice();
}
else if(article instanceof Menu){
totalPrice += ((Menu)article).getPrice();
}
}
}
public OrderList getOrderList() {
return orderList;
}
public void setOrderList(OrderList orderList) {
this.orderList = orderList;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
if(state.equals(State.LIVRE) || state.equals(State.PREPARE))
this.orderList.switchOrderList(this);
}
public PaymentType getPaymentType() {
return paymentType;
}
public void setPaymentType(PaymentType paymentType) {
this.paymentType = paymentType;
}
public Date getTime() {
return this.time;
}
public ArrayList<Object> getArticleList() {
return articleList;
}
public void setArticleList(ArrayList<Object> articleList) {
this.articleList = articleList;
}
public void addArticle(Object article){
if(article instanceof Article || article instanceof Menu){
Boolean removed = this.articleList.add(article);
if(article instanceof Article && removed){
this.totalPrice += ((Article) article).getPrice();
}
else if(article instanceof Menu && removed){
this.totalPrice += ((Menu) article).getPrice();
}
}
}
public void removeArticle(Object article){
if(article instanceof Article || article instanceof Menu){
Boolean removed = this.articleList.remove(article);
if(article instanceof Article && removed){
this.totalPrice -= ((Article) article).getPrice();
}
else if(article instanceof Menu && removed){
this.totalPrice -= ((Menu) article).getPrice();
}
}
}
public double getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(double totalPrice) {
this.totalPrice = totalPrice;
}
public Deliver getDeliver() {
return deliver;
}
public void setDeliver(Deliver deliver) {
this.deliver = deliver;
}}
public enum PaymentType {
INTERNET, CB, ESPECE, TICKET;}
Thanks
Problem is with line where you declared your private static int staticID = 0;
for each object creation of Order class and instance of order is created with all its memeber variable and static variable so for each order object this staticId = 0 at the time of object creation. Suppose your created first object Order1 here staticId = 0; and in custructor you incremented it to 1 so for order1 id= 1
2- Now for order2 Object created again this instance have staticId value = 0 not 1 (if you think i incremented it to 1 at the time of first order creation than you are taking static as wrong understanding bcs when ever a new object created all its member variable again created with it) so for order2 objects constructor you increment it 0 to 1 so for order2 id is again set to 1 not 2.
3- order3 continue same as order2.
Now solution is pass your id value in the constructor at the time of object creation like below:
Order order1 = new Order(1,Type.LIVRAISON,State.PREPARATION, PaymentType.CB, articleList, null);
Order order2 = new Order(2,Type.EMPORTE,State.PREPARATION, PaymentType.TICKET, articleList, null);
Order order3 = new Order(3,Type.EMPORTE,State.PREPARATION, PaymentType.TICKET, articleList, null);
parentActivity.model.getOrderlist().addOrder(order1);
parentActivity.model.getOrderlist().addOrder(order2);
parentActivity.model.getOrderlist().addOrder(order3);
And increase one parameter in Order Constructor:
public Order(int **orderid**,Type type, State state, PaymentType paymentType, ArrayList<Object> articleList, Deliver deliver) {
staticID++; **// dont use this staticId**
this.id = orderid;
this.type = type;
this.state = state;
this.paymentType = paymentType;
this.articleList = articleList;
this.deliver = deliver;
for(Object article:articleList){
if(article instanceof Article){
totalPrice += ((Article)article).getPrice();
}
else if(article instanceof Menu){
totalPrice += ((Menu)article).getPrice();
}
}
}
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);
I have a problem to send data using putExtra (of the a Adapter Class to an new Activity). I think that my problem is in Parcelable, but I cannot find where there are the problem.
Follow my class for you understand better.
Consultorio.class
public class Consultorio implements Parcelable {
private String nome;
private int photo;
public Consultorio() {
}
* #param nome
* #param photo
public Consultorio( String nome, int Photo)) {
this.nome = nome;
this.photo = photo;
}
/**
* #return
*/
public String getNome() {
return nome;
}
/**
* #param nome
*/
public void setNome(String nome) {
this.nome = nome;
}
public int getPhoto() {
return photo;
}
public void setPhoto(int photo) {
this.photo = photo;
}
//PARCELABLE
public Consultorio(Parcel parcel){
setNome(parcel.readString());
setPhoto(parcel.readInt());
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(photo);
dest.writeString(nome);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator<Consultorio>() {
#Override
public Consultorio createFromParcel(Parcel source) {
return new Consultorio(source);
}
#Override
public Consultorio[] newArray(int size) {
return new Consultorio[size];
}
};
public void readFromParcel(Parcel in) {
nome = in.readString();
photo = in.readInt();
}
}
Follow My Class Fragment (because I'm using TabLayout)
public class ClinicaMedicaFragment extends Fragment {
private List<Consultorio> consultorioList = new ArrayList<Consultorio>();
private ClinicaAdapter adapter;
private Toolbar toolbar;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.clinica_medica_fragment, container, false);
RecyclerView recyclerView = (RecyclerView) v.findViewById(R.id.clinica_recyclerView);
toolbar = (Toolbar) v.findViewById(R.id.tb_main);
GridLayoutManager manager = new GridLayoutManager(v.getContext(),
2, GridLayoutManager.VERTICAL, false);
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
return (position % 3 == 0 ? 2 : 1);
}
});
recyclerView.setLayoutManager(manager);
List<Consultorio> list = new ArrayList<Consultorio>();
Consultorio c0 = new Consultorio();
c0.setPhoto(R.mipmap.img1);
c0.setNome("Name 1");
Consultorio c1 = new Consultorio();
c1.setPhoto(R.mipmap.img2);
c1.setNome("Name 2");
Consultorio c2 = new Consultorio();
c2.setPhoto(R.mipmap.img3);
c2.setNome("Name 3");
list.add(c0);
list.add(c1);
list.add(c2);
consultorioList = list;
adapter = new ClinicaAdapter(list);
recyclerView.setAdapter(adapter);
return v;
}
Follow My CLASS Adapter (in this class I'm using putExtra for send datato an new Activity)
public class ClinicaAdapter extends RecyclerView.Adapter<ClinicaAdapter.ViewHolder>{
private List<Consultorio> consultorioList;
//protected Boolean isHomeList = false;
public ClinicaAdapter(List<Consultorio> data) {
consultorioList = data;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.clinica_medica_item, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final Consultorio consultorio = consultorioList.get(position);
holder.imageViewPhoto.setImageResource(consultorio.getPhoto());
holder.imageViewPhoto.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), ClinicaActivity.class);
intent.putExtra("consultorio", consultorio);
view.getContext().startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return consultorioList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageViewPhoto;
public ViewHolder(View itemView) {
super(itemView);
imageViewPhoto = (ImageView) itemView.findViewById(R.id.clinc_img);
}
}
Inmy Class Activity I pick up information by
Consultorio mConsultorio;
mConsultorio = getIntent().getParcelableExtra("consultorio");
The parcelable should maintain order of write and read members. Your writeToParcel method write int photo first and then string nome, but readFromParcel method read int photo secondly.
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(nome); // <- I changed nome firstly.
dest.writeInt(photo);
}
public void readFromParcel(Parcel in) {
nome = in.readString();
photo = in.readInt();
}
I strongly recommend you to find and install Android Pacelable Code Generator plugin in Android Studio. It will automatically generate Parcelable i/o of the class for you. After installing the plugin, just right click at the class name, and click "Generate..." > "Parcelable" menu.
How to show date or today , yesterday like text in between conversation
like whatsapp
MainActivity
public class MainActivity extends AppCompatActivity {
private ChatAdapter chatAdapter;
private RecyclerView recyclerView;
private Context context;
private int loggedInUserID;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bindRecyclerView();
// TODO get logged in user id and initialize into 'loggedInUserID'
}
#Override
protected void onResume() {
super.onResume();
getData();
}
private void getData() {
/**
*Your server call to get data and parse json to your appropriate model
* after parsing json to model simply call the
*/
List<ChatModel> chatModelList = ParseData.chatParser(jsonArray);
groupDataIntoHashMap(chatModelList);
}
private void bindRecyclerView() {
chatAdapter = new ChatAdapter(null);
chatAdapter.setUser(loggedInUserID);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(chatAdapter);
}
private void groupDataIntoHashMap(List<ChatModel> chatModelList) {
LinkedHashMap<String, Set<ChatModel>> groupedHashMap = new LinkedHashMap<>();
Set<ChatModel> list = null;
for (ChatModel chatModel : chatModelList) {
//Log.d(TAG, travelActivityDTO.toString());
String hashMapKey = DateParser.convertDateToString(chatModel.getChatTime());
//Log.d(TAG, "start date: " + DateParser.convertDateToString(travelActivityDTO.getStartDate()));
if (groupedHashMap.containsKey(hashMapKey)) {
// The key is already in the HashMap; add the pojo object
// against the existing key.
groupedHashMap.get(hashMapKey).add(chatModel);
} else {
// The key is not there in the HashMap; create a new key-value pair
list = new LinkedHashSet<>();
list.add(chatModel);
groupedHashMap.put(hashMapKey, list);
}
}
//Generate list from map
generateListFromMap(groupedHashMap);
}
private List<ListObject> generateListFromMap(LinkedHashMap<String, Set<ChatModel>> groupedHashMap) {
// We linearly add every item into the consolidatedList.
List<ListObject> consolidatedList = new ArrayList<>();
for (String date : groupedHashMap.keySet()) {
DateObject dateItem = new DateObject();
dateItem.setDate(date);
consolidatedList.add(dateItem);
for (ChatModel chatModel : groupedHashMap.get(date)) {
ChatModelObject generalItem = new ChatModelObject();
generalItem.setChatModel(chatModel);
consolidatedList.add(generalItem);
}
}
chatAdapter.setDataChange(consolidatedList);
return consolidatedList;
}
}
ChatModel.java
public class ChatModel implements Serializable {
private String messageId;
private int userId;
private String firstName;
private String userName;
private String message;
private Date chatTime;
//TODO generate getter and setter
}
ListObject.java (to determind the type of message)
public abstract class ListObject {
public static final int TYPE_DATE = 0;
public static final int TYPE_GENERAL_RIGHT = 1;
public static final int TYPE_GENERAL_LEFT = 2;
abstract public int getType(int userId);
}
DateObject.java
public class DateObject extends ListObject {
private String date;
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
#Override
public int getType(int userId) {
return TYPE_DATE;
}
}
ChatModelObject.java
public class ChatModelObject extends ListObject {
private ChatModel chatModel;
public ChatModel getChatModel() {
return chatModel;
}
public void setChatModel(ChatModel chatModel) {
this.chatModel = chatModel;
}
#Override
public int getType(int userId) {
if (this.chatModel.getUserId() == userId) {
return TYPE_GENERAL_RIGHT;
} else
return TYPE_GENERAL_LEFT;
}
}
DateParse.java to parse date for grouping the chat
public class DateParser {
private static DateFormat dateFormat1 = new SimpleDateFormat("dd/MM/yyyy");
public static String convertDateToString(Date date) {
String strDate = "";
strDate = dateFormat1.format(date);
return strDate;
}
}
ChatAdapter.java
public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<ListObject> listObjects;
private int loggedInUserId;
public ChatAdapter(List<ListObject> listObjects) {
this.listObjects = listObjects;
}
public void setUser(int userId) {
this.loggedInUserId = userId;
}
public void setDataChange(List<ListObject> asList) {
this.listObjects = asList;
//now, tell the adapter about the update
notifyDataSetChanged();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case ListObject.TYPE_GENERAL_RIGHT:
View currentUserView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_chat_list_row_right, parent, false);
viewHolder = new ChatRightViewHolder(currentUserView); // view holder for normal items
break;
case ListObject.TYPE_GENERAL_LEFT:
View otherUserView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_chat_list_row_left, parent, false);
viewHolder = new ChatLeftViewHolder(otherUserView); // view holder for normal items
break;
case ListObject.TYPE_DATE:
View v2 = inflater.inflate(R.layout.date_row, parent, false);
viewHolder = new DateViewHolder(v2);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
switch (viewHolder.getItemViewType()) {
case ListObject.TYPE_GENERAL_RIGHT:
ChatModelObject generalItem = (ChatModelObject) listObjects.get(position);
ChatRightViewHolder chatViewHolder = (ChatRightViewHolder) viewHolder;
chatViewHolder.bind(generalItem.getChatModel());
break;
case ListObject.TYPE_GENERAL_LEFT:
ChatModelObject generalItemLeft = (ChatModelObject) listObjects.get(position);
ChatLeftViewHolder chatLeftViewHolder = (ChatLeftViewHolder) viewHolder;
chatLeftViewHolder.bind(generalItemLeft.getChatModel());
break;
case ListObject.TYPE_DATE:
DateObject dateItem = (DateObject) listObjects.get(position);
DateViewHolder dateViewHolder = (DateViewHolder) viewHolder;
dateViewHolder.bind(dateItem.getDate());
break;
}
}
#Override
public int getItemCount() {
if (listObjects != null) {
return listObjects.size();
}
return 0;
}
#Override
public int getItemViewType(int position) {
return listObjects.get(position).getType(loggedInUserId);
}
public ListObject getItem(int position) {
return listObjects.get(position);
}
}
ChatRightViewHolder.java for current user message
public class ChatRightViewHolder extends RecyclerView.ViewHolder {
private final String TAG = ChatRightViewHolder.class.getSimpleName();
public ChatRightViewHolder(View itemView) {
super(itemView);
//TODO initialize your xml views
}
public void bind(final ChatModel chatModel) {
//TODO set data to xml view via textivew.setText();
}
}
ChatLeftViewHolder.java for display other user messages.
public class ChatLeftViewHolder extends RecyclerView.ViewHolder {
private final String TAG = ChatRightViewHolder.class.getSimpleName();
public ChatLeftViewHolder(View itemView) {
super(itemView);
//TODO initialize your xml views
}
public void bind(final ChatModel chatModel) {
//TODO set data to xml view via textivew.setText();
}
}
DateViewHolder.java to display date
public class DateViewHolder extends RecyclerView.ViewHolder {
public DateViewHolder(View itemView) {
super(itemView);
//TODO initialize your xml views
}
public void bind(final String date) {
//TODO set data to xml view via textivew.setText();
}
}
You need to create a new ViewHolder for that purpose
For example:
// Different types of rows
private static final int TYPE_ITEM_LEFT = 0;
private static final int TYPE_ITEM_RIGHT = 1;
private static final int TYPE_ITEM_DATE_CONTAINER = 2;
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
class ViewHolder0 extends RecyclerView.ViewHolder {
// Viewholder for row type 0
}
class ViewHolder1 extends RecyclerView.ViewHolder {
// Viewholder for row type 1
}
class ViewHolder2 extends RecyclerView.ViewHolder {
// Viewholder for row type 2
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, int position) {
if (viewHolder.getItemViewType() == TYPE_ITEM_LEFT) {
// Code to populate type 0 view here
} else if (viewHolder.getItemViewType() == TYPE_ITEM_RIGHT) {
// Code to populate type 1 view here
} else if (viewHolder.getItemViewType() == TYPE_ITEM_DATE_CONTAINER) {
// Code to populate type 2 view here
}
}
You just have to compare the date when scrolling and set the visibility of date view. The advantage of this is there's no hard-coded today/yesterday in data list and is able to refresh the correct date immediately (scrolling) after 12.00 a.m.
e.g. in your onBindViewHolder() in recycleview:
if (position != 0) {
processDate(holder.topDateTextView, myData.getDate()
, this.myDataList.get(position - 1).getDate()
, false)
;
} else {
processDate(holder.topDateTextView, data.getDay()
, null
, true)
;
}
Method to process that date view (Assume your list has format "dd/MM/yyyy"):
private void processDate(#NonNull TextView tv, String dateAPIStr
, String dateAPICompareStr
, boolean isFirstItem) {
SimpleDateFormat f = new SimpleDateFormat("dd/MM/yyyy");
if (isFirstItem) {
//first item always got date/today to shows
//and overkill to compare with next item flow
Date dateFromAPI = null;
try {
dateFromAPI = f.parse(dateAPIStr);
if (DateUtils.isToday(dateFromAPI.getTime())) tv.setText("today");
else if (DateUtils.isToday(dateFromAPI.getTime() + DateUtils.DAY_IN_MILLIS)) tv.setText("yesterday");
else tv.setText(dateAPIStr);
tv.setIncludeFontPadding(false);
tv.setVisibility(View.VISIBLE);
} catch (ParseException e) {
e.printStackTrace();
tv.setVisibility(View.GONE);
}
} else {
if (!dateAPIStr.equalsIgnoreCase(dateAPICompareStr)) {
try {
Date dateFromAPI = f.parse(dateAPIStr);
if (DateUtils.isToday(dateFromAPI.getTime())) tv.setText("today");
else if (DateUtils.isToday(dateFromAPI.getTime() + DateUtils.DAY_IN_MILLIS)) tv.setText("yesterday");
else tv.setText(dateAPIStr);
tv.setIncludeFontPadding(false);
tv.setVisibility(View.VISIBLE);
} catch (ParseException e) {
e.printStackTrace();
tv.setVisibility(View.GONE);
}
} else {
tv.setVisibility(View.GONE);
}
}
}
Note: You also need to do yourAdapter.notifyDataSetChanged(); if append new item to redraw to dismiss previous "today"/date after 12.00 a.m on the same page, not just rely on yourAdapter.notifyItemInserted(new_item_position) which doesn't redraw previous items.