I use retrofit2 to import data from each of the three tables.
Put the values in one list and show them in RecycleView.
But it shows the first result from the second run.
The second result shows from the third run.
The first run is nothing.
In the first run, Adapter's list.size() also gives zero.
I don't know why.
It's MainActivity.
public class HistoryActivity extends AppCompatActivity implements View.OnClickListener {
private TextView foodTextView, companyTextView, dateTextView, useMaterialTextView;
private ImageView dateChangeImgView;
Calendar calendar;
RecyclerView historyRecyclerView;
ApiInterface apiInterface;
RecyclerView.LayoutManager layoutManager;
List<CowInfoData> cowInfoDataList;
List<RiceInfoData> riceInfoDataList;
List<VegetableInfoData> vegetableInfoDataList;
List list = new ArrayList();
HistoryAdapter historyAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_history);
HistoryActivityInit();
Intent intent = getIntent();
String foodName = intent.getExtras().getString("food_name");
String companyName = intent.getExtras().getString("company_name");
foodTextView.setText(foodName);
companyTextView.setText(companyName);
}
private void HistoryActivityInit() {
foodTextView = findViewById(R.id.text_food_name);
companyTextView = findViewById(R.id.text_company_name);
dateChangeImgView = findViewById(R.id.imgview_date_change);
dateTextView = findViewById(R.id.text_date);
useMaterialTextView = findViewById(R.id.text_use_material);
historyRecyclerView = findViewById(R.id.recyclerview_history);
calendar = new GregorianCalendar();
// dateTextView.setText(new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime()));
layoutManager = new LinearLayoutManager(this);
historyRecyclerView.setLayoutManager(layoutManager);
historyRecyclerView.setHasFixedSize(true);
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.imgview_date_change:
chooseDate();
break;
}
}
private void chooseDate() {
final View dialogView = View.inflate(this, R.layout.dialog_date_picker, null);
final DatePicker datePicker = dialogView.findViewById(R.id.date_picker);
datePicker.updateDate(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(dialogView);
builder.setNegativeButton("Cancel", null);
builder.setPositiveButton("Ok", (dialog, which) -> {
calendar = new GregorianCalendar(datePicker.getYear(), datePicker.getMonth(), datePicker.getDayOfMonth());
dateTextView.setText(new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime()));
String f_name = foodTextView.getText().toString();
String c_name = companyTextView.getText().toString();
String d_date = dateTextView.getText().toString();
Log.e("HistoryActivity", f_name);
Log.e("HistoryActivity", c_name);
Log.e("HistoryActivity", d_date);
historyInquiry(f_name, c_name, d_date);
});
builder.show();
}
private void historyInquiry(String food_name, String company_name, String date) {
apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
Call<List<CowInfoData>> call = apiInterface.getHistory_cow(food_name, company_name, date);
call.enqueue(new Callback<List<CowInfoData>>() {
#Override
public void onResponse(Call<List<CowInfoData>> call, Response<List<CowInfoData>> response) {
cowInfoDataList = response.body();
list.addAll(cowInfoDataList);
}
#Override
public void onFailure(Call<List<CowInfoData>> call, Throwable t) {
Log.e("ErrorMessage", t.toString());
}
});
Call<List<RiceInfoData>> call2 = apiInterface.getHistory_rice(food_name, company_name, date);
call2.enqueue(new Callback<List<RiceInfoData>>() {
#Override
public void onResponse(Call<List<RiceInfoData>> call, Response<List<RiceInfoData>> response) {
riceInfoDataList = response.body();
list.addAll(riceInfoDataList);
}
#Override
public void onFailure(Call<List<RiceInfoData>> call, Throwable t) {
Log.e("ErrorMessage", t.toString());
}
});
Call<List<VegetableInfoData>> call3 = apiInterface.getHistory_vegetable(food_name, company_name, date);
call3.enqueue(new Callback<List<VegetableInfoData>>() {
#Override
public void onResponse(Call<List<VegetableInfoData>> call, Response<List<VegetableInfoData>> response) {
vegetableInfoDataList = response.body();
list.addAll(vegetableInfoDataList);
}
#Override
public void onFailure(Call<List<VegetableInfoData>> call, Throwable t) {
Log.e("ErrorMessage", t.toString());
}
});
historyAdapter = new HistoryAdapter(list, HistoryActivity.this);
historyRecyclerView.setAdapter(historyAdapter);
historyAdapter.notifyDataSetChanged();
}
}
It's Adapter.
public class HistoryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List list;
private Context context;
public HistoryAdapter(List list, Context context) {
this.list = list;
this.context = context;
}
#Override
public int getItemViewType(int position) {
if(list.get(position) instanceof CowInfoData) {
return 0;
} else if(list.get(position) instanceof RiceInfoData) {
return 1;
}
return 2;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if(viewType == 0) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_history_cow, parent, false);
CowHistoryViewHolder holder = new CowHistoryViewHolder(view);
return holder;
} else if(viewType == 1) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_history_rice, parent, false);
RiceHistoryViewHolder holder = new RiceHistoryViewHolder(view);
return holder;
} else {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_history_vegetable, parent, false);
VegetableHistoryViewHolder holder = new VegetableHistoryViewHolder(view);
return holder;
}
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder viewHolder, int position) {
if(this.getItemViewType(position) == 0) {
CowInfoData cowInfoData = (CowInfoData)list.get(position);
CowHistoryViewHolder holder = (CowHistoryViewHolder) viewHolder;
holder.cowCategoryTextView.setText(cowInfoData.getCow_category());
holder.cowCompanyTextView.setText(cowInfoData.getCow_packing_company());
holder.cowTrackingNumTextView.setText(cowInfoData.getCow_tracking_num());
holder.cowGradeTextView.setText(cowInfoData.getCow_grade());
Log.e("HistoryAdapter", cowInfoData.getCow_tracking_num());
} else if(this.getItemViewType(position) == 1) {
RiceInfoData riceInfoData = (RiceInfoData)list.get(position);
RiceHistoryViewHolder holder = (RiceHistoryViewHolder) viewHolder;
holder.riceNameTextView.setText(riceInfoData.getRice_name());
holder.riceCompanyTextView.setText(riceInfoData.getRice_company());
holder.riceProduceTextView.setText(riceInfoData.getProduce_date());
Log.e("HistoryAdapter", riceInfoData.getRice_name());
} else if(this.getItemViewType(position) == 2) {
VegetableInfoData vegetableInfoData = (VegetableInfoData)list.get(position);
VegetableHistoryViewHolder holder = (VegetableHistoryViewHolder) viewHolder;
holder.vegetableNameTextView.setText(vegetableInfoData.getVegetable_name());
holder.vegetableCompanyTextView.setText(vegetableInfoData.getVegetable_company());
Log.e("HistoryAdapter", vegetableInfoData.getVegetable_name());
} else {
Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show();
}
}
#Override
public int getItemCount() {
Log.e("HistoryAdapter", String.valueOf(list.size()));
return list.size();
}
public static class CowHistoryViewHolder extends RecyclerView.ViewHolder {
TextView cowCategoryTextView, cowCompanyTextView, cowTrackingNumTextView, cowGradeTextView;
public CowHistoryViewHolder(#NonNull View itemView) {
super(itemView);
cowCategoryTextView = itemView.findViewById(R.id.text_cow_category);
cowCompanyTextView = itemView.findViewById(R.id.text_cow_company);
cowTrackingNumTextView = itemView.findViewById(R.id.text_cow_tracking_num);
cowGradeTextView = itemView.findViewById(R.id.text_cow_grade);
}
}
public static class RiceHistoryViewHolder extends RecyclerView.ViewHolder {
TextView riceNameTextView, riceCompanyTextView, riceProduceTextView;
public RiceHistoryViewHolder(#NonNull View itemView) {
super(itemView);
riceNameTextView = itemView.findViewById(R.id.text_rice_name);
riceCompanyTextView = itemView.findViewById(R.id.text_rice_company);
riceProduceTextView = itemView.findViewById(R.id.text_rice_produce);
}
}
public static class VegetableHistoryViewHolder extends RecyclerView.ViewHolder {
TextView vegetableNameTextView, vegetableCompanyTextView;
public VegetableHistoryViewHolder(#NonNull View itemView) {
super(itemView);
vegetableNameTextView = itemView.findViewById(R.id.text_vegetable_name);
vegetableCompanyTextView = itemView.findViewById(R.id.text_vegetable_company);
}
}
}
Plz Help me.
You are not calling notifyDataSetChanged(); after updating data
just add historyAdapter.notifyDataSetChanged(); after list.addAll(cowInfoDataList);
also
historyAdapter = new HistoryAdapter(list, HistoryActivity.this);
historyRecyclerView.setAdapter(historyAdapter);
These two lines should be executed before calling API. May be inside oncreate()
Related
I am developing an android app which is able to search for users and also restaurants. So I am using a custom adapter to handles two types of items. The objects I need to display are User and Eateries. And the objects require completely different layouts to display them.
Here is my SearchingFragment which contains the adapter:
public class SearchingFragment extends Fragment {
private SearchView searchView;
private RecyclerView resultList;
private RecyclerView.Adapter<RecyclerView.ViewHolder> adapter;
final int VIEW_TYPE_USER = 0;
final int VIEW_TYPE_EATERIES = 1;
private ArrayList<User> userArrayList = new ArrayList<User>();
private ArrayList<Eateries2> eateriesArrayList = new ArrayList<Eateries2>();
FirebaseFirestore db = FirebaseFirestore.getInstance();
String TAG;
private OnItemClickListener mListener;
public interface OnItemClickListener {
void OnItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListener = listener;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_searching, container, false);
//return inflater.inflate(R.layout.fragment_searching, container, false);
searchView = root.findViewById(R.id.searchView);
resultList = root.findViewById(R.id.resultList);
resultList.setHasFixedSize(true);
resultList.setLayoutManager(new LinearLayoutManager(getActivity()));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
if(newText.trim().isEmpty()){
userArrayList = new ArrayList<>();
eateriesArrayList = new ArrayList<>();
}
else {
userArrayList = new ArrayList<>();
eateriesArrayList = new ArrayList<>();
FirestoreUserSearch(newText);
}
return false;
}
});
return root;
}
private void FirestoreUserSearch(String searchText) {
db.collection("users")
.orderBy("username")
.startAt(searchText)
.endAt(searchText + "\uf8ff")
.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
for(DocumentChange document :queryDocumentSnapshots.getDocumentChanges()){
userArrayList.add(document.getDocument().toObject(User.class));
adapter.notifyDataSetChanged();
}
}
});
db.collection("eateries")
.orderBy("placeName")
.startAt(searchText)
.endAt(searchText + "\uf8ff")
.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
for(DocumentChange doc : queryDocumentSnapshots.getDocumentChanges()){
String placeId = doc.getDocument().getString("placeID");
String placeName = doc.getDocument().getString("placeName");
List<String> category = (List<String>)doc.getDocument().get("category");
String address = doc.getDocument().getString("address");
Double rating = doc.getDocument().getDouble("rating");
Double price_level = doc.getDocument().getDouble("price_level");
Eateries2 eateries = new Eateries2(address, category, placeId, placeName, rating, price_level);
eateriesArrayList.add(eateries);
adapter.notifyDataSetChanged();
}
}
});
adapter = new RecyclerView.Adapter<RecyclerView.ViewHolder>() {
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view;
if (viewType==VIEW_TYPE_USER){
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.user_list_layout,parent,false);
return new SearchingFragment.UserViewHolder(view);
}
if(viewType==VIEW_TYPE_EATERIES){
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.eateries_list_layout,parent,false);
return new SearchingFragment.EateriesViewHolder(view,mListener);
}
return null;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
if(holder instanceof SearchingFragment.UserViewHolder){
((SearchingFragment.UserViewHolder) holder).userName.setText(userArrayList.get(position).getUsername());
((SearchingFragment.UserViewHolder) holder).category.setText("User");
((SearchingFragment.UserViewHolder) holder).userImage.setImageURI(null);
if(userArrayList.get(position).getPhoto()!=null){
Uri uri=Uri.parse(userArrayList.get(position).getPhoto());
Glide.with(getContext()).load(uri).into(((SearchingFragment.UserViewHolder) holder).userImage);
}
}
if(holder instanceof SearchingFragment.EateriesViewHolder){
((SearchingFragment.EateriesViewHolder) holder).placeName.setText(eateriesArrayList.get(position-userArrayList.size()).getPlaceName());
((SearchingFragment.EateriesViewHolder) holder).category.setText("Eatery\n"+eateriesArrayList.get(position-userArrayList.size()).getCategory());
((SearchingFragment.EateriesViewHolder) holder).address.setText(Html.fromHtml(eateriesArrayList.get(position-userArrayList.size()).getAddress()));
((EateriesViewHolder) holder).ratingBar.setRating(Float.parseFloat(eateriesArrayList.get(position-userArrayList.size()).getRating().toString()));
((EateriesViewHolder) holder).ratingBar.setIsIndicator(true);
((EateriesViewHolder) holder).priceRateBar.setRating(Float.parseFloat(eateriesArrayList.get(position-userArrayList.size()).getPrice_level().toString()));
List<Place.Field> fields = Arrays.asList(Place.Field.PHOTO_METADATAS);
FetchPlaceRequest placeRequest = FetchPlaceRequest.newInstance(eateriesArrayList.get(position-userArrayList.size()).getPlaceID(), fields);
String api = "AIzaSyDz5BGny6Lsp7gW-uJznoLVZS4riEdfnF0";
Places.initialize(getContext(), api);
PlacesClient placesClient = Places.createClient(getContext());
placesClient.fetchPlace(placeRequest).addOnSuccessListener((response) -> {
Place place = response.getPlace();
PhotoMetadata photoMetadata = place.getPhotoMetadatas().get(0);
String attributions = photoMetadata.getAttributions();
FetchPhotoRequest photoRequest = FetchPhotoRequest.builder(photoMetadata)
.build();
placesClient.fetchPhoto(photoRequest).addOnSuccessListener((fetchPhotoResponse) -> {
Bitmap bitmap = fetchPhotoResponse.getBitmap();
((SearchingFragment.EateriesViewHolder) holder).eateryImage.setImageBitmap(bitmap);
// imageView.setImageBitmap(bitmap);
}).addOnFailureListener((exception) -> {
if (exception instanceof ApiException) {
ApiException apiException = (ApiException) exception;
int statusCode = apiException.getStatusCode();
// Handle error with given status code.
Log.e(TAG, "Place not found: " + exception.getMessage());
}
});
});
}
}
#Override
public int getItemCount() {
return userArrayList.size()+eateriesArrayList.size();
}
#Override
public int getItemViewType(int position){
if(position<userArrayList.size()){
return VIEW_TYPE_USER;
}
if(position-userArrayList.size()<eateriesArrayList.size()){
return VIEW_TYPE_EATERIES;
}
return -1;
}
};
resultList.setAdapter(adapter);
}
private class UserViewHolder extends RecyclerView.ViewHolder {
TextView userName;
ImageView userImage;
TextView category;
UserViewHolder(View itemView) {
super(itemView);
userName = itemView.findViewById(R.id.userName);
userImage = itemView.findViewById(R.id.userImage);
category = itemView.findViewById(R.id.catagory);
}
}
private class EateriesViewHolder extends RecyclerView.ViewHolder{
TextView placeName;
TextView category;
TextView address;
ImageView eateryImage;
RatingBar ratingBar,priceRateBar;
EateriesViewHolder(View itemView,OnItemClickListener listener){
super(itemView);
placeName = itemView.findViewById(R.id.placeName);
category = itemView.findViewById(R.id.catagory);
address = itemView.findViewById(R.id.address);
eateryImage = itemView.findViewById(R.id.eateryImage);
ratingBar = itemView.findViewById(R.id.ratingBar);
priceRateBar = itemView.findViewById(R.id.priceRateBar);
}
}
So, how can I set different OnClickListener for my adapter? Much appreciate.
You can use interface for different on click listener
you can create interface class
public interface ICallback {
public void onItemClick(int pos);
}
then call interface class on adapter and click on item click
holder.textview.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
iCallback.onItemClick(position);
}
});
after final call interface class in activity or fragment
iCallback = new ICallback() {
#Override
public void onItemClick(int pos) {
Intent intent = new Intent(HomeActivity.this,SecondActivity.class);
startActivity(intent);
}
};
i : First Way
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if([this method is Override method]getItemViewType(position) == VIEW_TYPE_USER){
// here USER logic
}else{
// here EATERIES logic
}
}
});
II ) Second Way
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
if(holder instanceof SearchingFragment.UserViewHolder){
((SearchingFragment.UserViewHolder) holder).userName.setText(userArrayList.get(position).getUsername());
((SearchingFragment.UserViewHolder) holder).category.setText("User");
((SearchingFragment.UserViewHolder) holder).userImage.setImageURI(null);
if(userArrayList.get(position).getPhoto()!=null){
Uri uri=Uri.parse(userArrayList.get(position).getPhoto());
Glide.with(getContext()).load(uri).into(((SearchingFragment.UserViewHolder) holder).userImage);
}
((SearchingFragment.UserViewHolder) holder).itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
}
if(holder instanceof SearchingFragment.EateriesViewHolder){
((SearchingFragment.EateriesViewHolder) holder).placeName.setText(eateriesArrayList.get(position-userArrayList.size()).getPlaceName());
((SearchingFragment.EateriesViewHolder) holder).category.setText("Eatery\n"+eateriesArrayList.get(position-userArrayList.size()).getCategory());
((SearchingFragment.EateriesViewHolder) holder).address.setText(Html.fromHtml(eateriesArrayList.get(position-userArrayList.size()).getAddress()));
((EateriesViewHolder) holder).ratingBar.setRating(Float.parseFloat(eateriesArrayList.get(position-userArrayList.size()).getRating().toString()));
((EateriesViewHolder) holder).ratingBar.setIsIndicator(true);
((EateriesViewHolder) holder).priceRateBar.setRating(Float.parseFloat(eateriesArrayList.get(position-userArrayList.size()).getPrice_level().toString()));
List<Place.Field> fields = Arrays.asList(Place.Field.PHOTO_METADATAS);
FetchPlaceRequest placeRequest = FetchPlaceRequest.newInstance(eateriesArrayList.get(position-userArrayList.size()).getPlaceID(), fields);
String api = "AIzaSyDz5BGny6Lsp7gW-uJznoLVZS4riEdfnF0";
Places.initialize(getContext(), api);
PlacesClient placesClient = Places.createClient(getContext());
placesClient.fetchPlace(placeRequest).addOnSuccessListener((response) -> {
Place place = response.getPlace();
PhotoMetadata photoMetadata = place.getPhotoMetadatas().get(0);
String attributions = photoMetadata.getAttributions();
FetchPhotoRequest photoRequest = FetchPhotoRequest.builder(photoMetadata)
.build();
placesClient.fetchPhoto(photoRequest).addOnSuccessListener((fetchPhotoResponse) -> {
Bitmap bitmap = fetchPhotoResponse.getBitmap();
((SearchingFragment.EateriesViewHolder) holder).eateryImage.setImageBitmap(bitmap);
// imageView.setImageBitmap(bitmap);
}).addOnFailureListener((exception) -> {
if (exception instanceof ApiException) {
ApiException apiException = (ApiException) exception;
int statusCode = apiException.getStatusCode();
// Handle error with given status code.
Log.e(TAG, "Place not found: " + exception.getMessage());
}
});
});
((SearchingFragment.EateriesViewHolder) holder).itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
}
}
}
Update your ViewHolders Like given below
private class UserViewHolder extends RecyclerView.ViewHolder {
TextView userName;
ImageView userImage;
TextView category;
UserViewHolder(View itemView) {
super(itemView);
userName = itemView.findViewById(R.id.userName);
userImage = itemView.findViewById(R.id.userImage);
category = itemView.findViewById(R.id.catagory);
// set Click Listener of whole item view or your desired view
itemView.setOnClickListener(view -> {
User user = userArrayList.get(getAdapterPosition());
// do whatever you want to
});
}
}
private class EateriesViewHolder extends RecyclerView.ViewHolder {
TextView placeName;
TextView category;
TextView address;
ImageView eateryImage;
RatingBar ratingBar, priceRateBar;
EateriesViewHolder(View itemView) {
super(itemView);
placeName = itemView.findViewById(R.id.placeName);
category = itemView.findViewById(R.id.catagory);
address = itemView.findViewById(R.id.address);
eateryImage = itemView.findViewById(R.id.eateryImage);
ratingBar = itemView.findViewById(R.id.ratingBar);
priceRateBar = itemView.findViewById(R.id.priceRateBar);
// set Click Listener of whole item view or your desired view
itemView.setOnClickListener(view -> {
Eateries2 Eateries2 = eateriesArrayList.get(getAdapterPosition());
// do whatever you want to
});
}
}
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?
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");
From a JSON array that I am parsing, I want to send a particular object value (using intent putExtra) to another activity. I have read this this question
and the accepted answer but I don't want to send all the values, in my case I only want to send the news_id as an integer to NewsDetails.class.
And I tried using the accepted answer to do it but I got stuck.
MainActivity
public class MainActivity extends AppCompatActivity{
private final String TAG = "MainActivity";
//Creating a list of newss
private List<NewsItems> mNewsItemsList;
//Creating Views
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "Device rotated and onCreate called");
//Initializing Views
recyclerView = (RecyclerView) findViewById(R.id.news_recycler);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
//Initializing the newslist
mNewsItemsList = new ArrayList<>();
adapter = new NewsAdapter(mNewsItemsList, this);
recyclerView.setAdapter(adapter);
//Caling method to get data
getData();
}
//This method will get data from the web api
private void getData(){
Log.d(TAG, "getData called");
//Showing progress dialog
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setCancelable(false);
mProgressDialog.setMessage(this.getResources().getString(R.string.load_news));
mProgressDialog.show();
//Creating a json request
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(ConfigNews.GET_URL,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, "onResponse called");
//Dismissing the progress dialog
if (mProgressDialog != null) {
mProgressDialog.hide();
}
/*progressDialog.dismiss();*/
//calling method to parse json array
parseData(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
//Creating request queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to the queue
requestQueue.add(jsonArrayRequest);
}
//This method will parse json data
private void parseData(JSONArray array){
Log.d(TAG, "Parsing array");
for(int i = 0; i<array.length(); i++) {
NewsItems newsItem = new NewsItems();
JSONObject jsonObject = null;
try {
jsonObject = array.getJSONObject(i);
newsItem.setNews_title(jsonObject.getString(ConfigNews.TAG_NEWS_TITLE));
newsItem.setNews_excerpt(jsonObject.getString(ConfigNews.TAG_NEWS_EXCERPT));
newsItem.setNewsId(jsonObject.getInt(ConfigNews.TAG_NEWS_ID));
} catch (JSONException w) {
w.printStackTrace();
}
mNewsItemsList.add(newsItem);
}
adapter.notifyItemRangeChanged(0, adapter.getItemCount());
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy called");
if (mProgressDialog != null){
mProgressDialog.dismiss();
Log.d(TAG, "mProgress dialog dismissed");
}
}
}
NewsItems class
public class NewsItems {
private String news_title;
private String news_excerpt;
private int news_id;
public String getNews_title() {
return news_title;
}
public void setNews_title(String news_title) {
this.news_title = news_title;
}
public String getNews_excerpt() {
return news_excerpt;
}
public void setNews_excerpt(String news_excerpt) {
this.news_excerpt = news_excerpt;
}
public int getNews_id() {
return news_id;
}
public void setNews_id(int news_id) {
this.news_id = news_id;
}
}
NewsAdapter
public class NewsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private ImageLoader imageLoader;
private Context mContext;
//List of newss
private List<NewsItems> mNewsItems;
private final int VIEW_ITEM = 0;
private final int VIEW_PROG = 1;
private int lastPosition = -1;
public NewsAdapter(List<NewsItems> newsItems, Context context) {
super();
//Getting all newss
this.mNewsItems = newsItems;
this.mContext = context;
}
#Override
public int getItemViewType(int position) {
if (isPositionItem(position))
return VIEW_ITEM;
return VIEW_PROG;
}
private boolean isPositionItem(int position) {
return position != getItemCount()-1;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder (ViewGroup parent, int viewType) {
if (viewType == VIEW_ITEM) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.news_summ, parent, false);
return new TextViewHolder(v, mContext);
} else if (viewType == VIEW_PROG){
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerfooter, parent, false);
return new ProgressViewHolder(v);
}
return null;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof TextViewHolder) {
NewsItems newsList = mNewsItems.get(position);
((TextViewHolder) holder).newsTitle.setText(newsList.getNews_title());
((TextViewHolder) holder).newsExcerpt.setText(newsList.getNews_excerpt());
((TextViewHolder) holder).newsId.setText(String.valueOf(newsList.getNewsId()));
} else {
((ProgressViewHolder) holder).progressBar.setIndeterminate(true);
((ProgressViewHolder) holder).loadButton.setText(R.string.reload);
}
}
#Override
public int getItemCount(){
//Return the number of items in the data set
return mNewsItems.size();
}
public static class TextViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView newsTitle,newsExcerpt, newsId;
public ImageButton imageButton;
public NewsItems dNewsItems;
private Context context;
public TextViewHolder (final View newsView, final Context context) {
super(newsView);
this.context = context;
newsTitle = (TextView) newsView.findViewById(R.id.news_title);
newsExcerpt = (TextView) newsView.findViewById(R.id.news_excerpt);
newsId = (TextView) newsView.findViewById(R.id.news_id);
newsExcerpt.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v.getId() == newsExcerpt.getId()) {
Intent intent = new Intent(context, NewsDetails.class);
Bundle bundle = new Bundle();
bundle.putSerializable("PostId", //This is where I got confused);
}
}
}
}
public static class ProgressViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
Button loadButton;
ProgressBar progressBar;
public ProgressViewHolder(View footerView){
super(footerView);
loadButton = (Button) footerView.findViewById(R.id.reload_button);
progressBar = (ProgressBar) footerView.findViewById(R.id.progress_load);
loadButton.setOnClickListener(this);
if(NetworkCheck.isAvailableAndConnected(footerView.getContext())) {
progressBar.setVisibility(View.VISIBLE);
} else if (!NetworkCheck.isAvailableAndConnected(footerView.getContext())) {
loadButton.setVisibility(View.VISIBLE);
}
}
#Override
public void onClick(View v) {
if (v.getId() == loadButton.getId()) {
//
}
}
}
}
You can send single value also instead of complete object like this -
#Override
public void onClick(View v) {
if (v.getId() == newsExcerpt.getId()) {
Intent intent = new Intent(context, NewsDetails.class);
intent.putExtra("PostId",<your_news_id_here>);
startActivity(intent);
}
}
}
In your case, remove onClick(View v) and change your onBindViewHolder() to setOnClickListener() on newsExcerpt like this -
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof TextViewHolder) {
NewsItems newsList = mNewsItems.get(position);
((TextViewHolder) holder).newsTitle.setText(newsList.getNews_title());
((TextViewHolder) holder).newsExcerpt.setText(newsList.getNews_excerpt());
((TextViewHolder) holder).newsId.setText(String.valueOf(newsList.getNewsId()));
((TextViewHolder) holder).newsExcerpt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, NewsDetails.class);
intent.putExtra("PostId",newsList.getNewsId()); //Any getter of your class you want
startActivity(intent);
});
} else {
((ProgressViewHolder) holder).progressBar.setIndeterminate(true);
((ProgressViewHolder) holder).loadButton.setText(R.string.reload);
}
}
I don't want to send all the values
You dont' have to send all, It's up to you and your needs.
Intent i = new Intent(context, DestActivity.class);
i.putExtra(KEY_NEWS_ID, news_id );
On the other end:
int news_id = getIntent().getIntExtra(KEY_NEWS_ID, defaultValue);
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.