Android ListView all views shows last item data - java

I really need some good hint.... i have been hours debugging this (((...
public class Travel {
public static String from, to;
Travel(String f, String t) {
this.from = f;
this.to = t;
}
}
final class NotesAdapter extendes ArrayAdapter<Travel>{
private final List<Travel> myC;
public NotesAdapter(Context context, int resource, List<Travel> myCt) {
super(context, resource, myCt);
this.myC = myCt;
}
#Override
public int getCount() {
return myC.size();
}
#Override
public Travel getItem(int position) {
return myC.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup adapterView) {
Travel trv = myC.get(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.my_lists, adapterView, false);
}
TextView from = (TextView)convertView.findViewById(R.id.tv_from);
TextView to = (TextView)convertView.findViewById(R.id.tv_to);
from.setText(trv.from);//.getMFrom()
to.setText(trv.to);//.getMTo()
return convertView;
}
In NotesAdapter i have implemented only the method you see here.
Then in the main activity i launch startactivityforresult and in the onactivityresults i add elements to the List object.
List<Travel> myCities = new ArrayList<Travel>();
the List object is initialized as an ArrayList (...new ArrayList<>()...).
I also have:
mList = (ListView)findViewById(R.id.for_lists);
na = new NotesAdapter(this,R.layout.my_lists,myCities);
So:
nCity = data.getStringExtra("content");
to collect the new string
myCities.add(new Travel("Home Town",nCity));
to add a new travel.... and:
na.notifyDataSetChanged();
mList.setAdapter(na);
this is the all code:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == MY_REQUEST_CODE){
if(resultCode == RESULT_OK){
nCity = data.getStringExtra("content");
if (!myCities.contains(nCity)) {
myCities.add(new Travel("Home Town",nCity));
na.notifyDataSetChanged();
} else {
Toast.makeText(this,"This City has already been added",Toast.LENGTH_LONG).show();
}
}
else {
//do something when user refused to complete action
}
hT.setText("Home Town");
iB.setText(infoBar);
na.notifyDataSetChanged();
mList.setAdapter(na);
mList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
}
});
}
else {
// not my business another request
}
}
When i use just a List of String all works perfectly.
The result with a List of Travel is that all views in the listview show the last added travel.
For layout files i use basic implementations.
Please help... ^_^

na is never set to List until you call mList.setAdapter(na);. You don't need to call na.notifyDataSetChanged();
Please add one new method in NotesAdapter adapter. This method will update data:
public void updateData(List<Travel> myCt){
this.myC = myCt;
}
then update your code
na.notifyDataSetChanged();
mList.setAdapter(na);
with
na.updateData(myCities);
mList.setAdapter(na);

The problem was static
public static String from, to

Related

How to remove the data from activity immediately after closing it

I'm creating an Android app, the data that i'm sending through intent is being retrieved every time i click on the item.
I'm sending the retrieved data(which it's a subcollection that is being retrieved every time i click on item) through the intent,and all data receives in an arraylist, so the listener don't know if the same data existed in the arraylist,because the data are in the other activity.
when i click for the first time the data displayed normally in ItemMarkerActivity but when i go back and click again on the same item i see the data load again in the recycler view,and added to the previous same data, i'm using the technique of removing the data onStop but it didn't work perfectly,because i need to close all activities to see that the data removed, i tried to send the CollectionReference through intent but i couldn't do. so I need a way of removing the data immediately after closing the activity, and if anyone has another approach for solving this problem it would better.
Thanks in advance
adapter.setOnItemClickListener(new MarketAdapterRecyclerView.OnItemClickListener() {
#Override
public void onItemClick(DocumentSnapshot documentSnapshot, int position) {
CollectionReference path = documentSnapshot.getReference().collection("ShoppingItems");
listener = path.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot queryDocumentSnapshots, #Nullable FirebaseFirestoreException e) {
if (e != null) {
return;
}
for (DocumentChange dc : queryDocumentSnapshots.getDocumentChanges()) {
if (dc.getType() == DocumentChange.Type.ADDED) {
item = dc.getDocument().toObject(Item.class);
itemList.add(item);
}
}
Intent intent = new Intent (shoppingActivity.this, ItemMarkerActivity.class);
Log.v(TAG,"###################################" + itemList.toString());
intent.putExtra("keyName", itemList);
startActivity(intent);
}
});
}
}
The Activity That Receives The data
The Manifest
public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> implements Parcelable{
public ArrayList<Item> ItemList;
public Context mContext;
private onMallListener mOnMallListener;
private static final int NO_POSITION = -1;
public ItemAdapter(ArrayList<Item> ItemList, Context mContext, onMallListener mOnMallListener) {
this.ItemList = ItemList;
this.mContext = mContext;
this.mOnMallListener = mOnMallListener;
}
protected ItemAdapter(Parcel in) {
ItemList = in.createTypedArrayList(Item.CREATOR);
}
public static final Creator<ItemAdapter> CREATOR = new Creator<ItemAdapter>() {
#Override
public ItemAdapter createFromParcel(Parcel in) {
return new ItemAdapter(in);
}
#Override
public ItemAdapter[] newArray(int size) {
return new ItemAdapter[size];
}
};
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.activity_card_view_item, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(view, mOnMallListener);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int i) {
Item item = ItemList.get(i);
viewHolder.itemType.setText(ItemList.get(i).getItemType());
Picasso.with(mContext)
.load(item.getImageUrl())
.fit()
.centerCrop().into(viewHolder.imageUrl);
}
#Override
public int getItemCount() {
return ItemList.size();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeTypedList(ItemList);
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
View mView;
public TextView price;
public TextView description;
public TextView itemType;
public ImageView imageUrl;
onMallListener onMallListener;
public ViewHolder(#NonNull View itemView, onMallListener mOnMallListener) {
super(itemView);
mView = itemView;
itemType = (TextView) mView.findViewById(R.id.card_view_image_title);
imageUrl = (ImageView) mView.findViewById(R.id.card_view_image);
this.onMallListener = mOnMallListener;
mView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(mOnMallListener != null){
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION){
mOnMallListener.onMallClick(position);
}
}
}
}
public interface onMallListener{
void onMallClick(int position);
}
}
Save data using Room database in first activity and retrieve it in second.
In any place of your code (and in any activity's callback) you can clean db and all lists/recyclers which listen this data.
https://developer.android.com/training/data-storage/room
Hope it'll help

Dynamic Spinners - if an item is selected from one spinner, hide it from other spinners - Android

How to hide an item from other spinners that is currently selected in one spinner?
I've tried removing the items via ArrayList of strings and ArrayAdapters, but I've noticed as soon as it's removed from the list, the selection is no longer referenced to the list item (because it does not exist anymore).
Now suppose, I have 4 spinner that are created dynamically and they all have the same ArrayList as their resource and now i would like to use this adapter to fetch the position of the selected item from 1 spinner and then hide it from 3 other spinners.
for (int i = 0; i < numberOfStops; i++) {
AddStopView stopView = new AddStopView(getActivity());
stopView.setCallback(BaseBookingFragment.this);
stopView.setPassengerNames(extraPassengerNames);
stopViews.add(stopView);
parent.addView(stopView, viewPosition);
}
In above code i am creating Stop Views dynamically and each Stop View having Passenger Name spinner. And these all spinners have the same ArrayList as their resource.
piece of code from AddStopView.java
public AddStopView(Context context) {
super(context);
initialize();
}
public void setCallback(StopViewCallback callback) {
this.callback = callback;
}
public void setPassengerNames(List<String> passengerNames) {
this.passengerNames = passengerNames;
passengerAdapter.setNames(passengerNames);
}
private void initialize() {
inflate(getContext(), R.layout.view_stop, this);
passengerAdapter = new ExtraPassengerAdapter(getContext());
passengerAdapter.setNames(passengerNames);
nameSpinner.setAdapter(passengerAdapter);
nameSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (view == null) {
return;
}
passengerName = (String) view.getTag();
if (position != 0)
callback.updatePassengerList(AddStopView.this, (position - 1));
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
code of call back of nameSpinner.setOnItemSelectedListener
#Override
public void updatePassengerList(AddStopView addStopView, int position) {
for (String passName : extraPassengerNames) {
if (addStopView.getPassengerName().equals(passName)) {
extraPassengerNames.remove(passName);
break;
}
}
for (AddStopView stopView : stopViews) {
if (!stopView.equals(addStopView))
stopView.setPassengerNames(extraPassengerNames);
}
}
code from ExtraPassengerAdapter.java
public class ExtraPassengerAdapter extends BaseAdapter {
private List<String> names = new ArrayList<>();
private Context context;
public ExtraPassengerAdapter(Context context) {
this.context = context;
names.add(get0Position());
}
public void setNames(List<String> names) {
this.names.clear();
this.names.add(get0Position());
this.names.addAll(names);
notifyDataSetChanged();
}
#Override
public int getCount() {
return names.size();
}
#Override
public String getItem(int position) {
return names.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = (TextView) LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_stop, parent, false);
String name = getItem(position);
textView.setText(name);
textView.setTag(name);
return textView;
}
private String get0Position() {
return context.getString(R.string.passenger_name);
}
}
I think the right way to solve you problem is to create one list with all possible options and 4 lists with 4 adapters for each spinner. When something selected you update each list according to logic you described and call adapter.notifyDataSetChanged() for each adapter.

Add search filter to my listview

Good evening,
It's true that I have found some tutorial on creating a search bar for ListView. Among those that I followed is: Android Adding Search Functionality to ListView. The code works fine but I can not adapt it to my list. I had to restart my project from the beginning because I messed. I am a beginner in Android programming and really need help. Here is my code:
ShoppingListActivity.java
public class ShoppingListActivity extends Activity {
private List<Produit> mCartList;
private ProduitAdapter mProductAdapter;
EditText inputSearch;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.shoppinglist);
mCartList = ShoppingListHelper.getCartList();
// Make sure to clear the selections
for(int i=0; i<mCartList.size(); i++) {
mCartList.get(i).selected = false;
}
// Create the list
final ListView listViewCatalog = (ListView) findViewById(R.id.ListViewCatalog);
mProductAdapter = new ProduitAdapter(mCartList, getLayoutInflater(), true);
listViewCatalog.setAdapter(mProductAdapter);
inputSearch = (EditText) findViewById(R.id.search);
inputSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { }
#Override
public void afterTextChanged(Editable arg0) {
String text = inputSearch.getText().toString().toLowerCase(Locale.getDefault());
mProductAdapter.filter(text);}
});
listViewCatalog.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Intent productDetailsIntent = new Intent(getBaseContext(),ProduitDetailsActivity.class);
productDetailsIntent.putExtra(ShoppingListHelper.PRODUCT_INDEX, position);
startActivity(productDetailsIntent);
}
});
}
and this is what contains ShoppingListHelper.java :
public static List<Produit> getCatalog(Resources res){
if(catalog == null) {
catalog = new Vector<Produit>();
catalog.add(new Produit("Nutella", res
.getDrawable(R.drawable.nutella),
"Pate à tartiner au chocolat, au bon goût de noisettes", 750));
}
return catalog;
}
And ProduitAdapter.java
public class ProduitAdapter extends BaseAdapter {
private List<Produit> mProductList;
private LayoutInflater mInflater;
private boolean mShowQuantity;
private ArrayList<Produit> arraylist;
public ProduitAdapter(List<Produit> list, LayoutInflater inflater, boolean showQuantity) {
mProductList = list;
mInflater = inflater;
mShowQuantity = showQuantity;
}
#Override
public int getCount() {
return mProductList.size();
}
#Override
public Object getItem(int position) {
return mProductList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
mProductList.clear();
if (charText.length() == 0) {
mProductList.addAll(arraylist);
}
else
{
for (Produit wp : arraylist)
{
if (wp.getProduct().toLowerCase(Locale.getDefault()).startsWith(charText))
{
mProductList.add(wp);
}
}
}
notifyDataSetChanged();
}
I use eclipse JUNO.
EDITED:
As you see in my code I've implemented a filter but my editText don't work! in compilation no errors shown!
Thank you in advance.

How to update data in one arraylist with two arrayadapter in different activity

I am trying to use two different ArrayAdapter(separately in to two Activity) with one Arraylist. The first ArrayAdapter does the Increment for the Quantity and the second does the Decrement. Then all of the Data from the first ArrayAdapter will be transfer to the second ArrayAdapter, but only the Data with Quantity greater than 1 will be displayed. All of the previous task seems to be working fine, until I tried to Decrement a Quantity(It shows that the data decements) and try to check if changes were saved by going back to the first Activity and back again to the second Activity. What happens is that changes made by the Decrement is being ignored and resets the data from when the item was Incremented. I know it's kinda messed up, but I hope you can help me what am I doing wrong.
EDIT: I am using two ArrayAdapter because I want to display the quantity in the second adapter, along with other elements.
Here is my codes:
myProductAdapter.java(Increment Adapter)
public class myProductAdapter extends ArrayAdapter<myProduct> {
public class ViewHolder{
Button addItem;
}
public myProductAdapter(Context context, ArrayList<myProduct> myProducts) {
super(context, 0, myProducts);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final myProduct product = getItem(position);
final ViewHolder viewHolder;
//Some Codes Here..
viewHolder.addItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
product.productQuantity ++;
Toast.makeText(getContext(), "" + product.productQuantity(), Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
}
myOrderAdapter.java(Decerement Adapter)
public class myOrderAdapter extends ArrayAdapter<myProduct> {
public class ViewHolder{
Button minusItem;
}
public myOrderAdapter(Context context, ArrayList<myProduct> orders){
super(context, 0, orders);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final myProduct order = getItem(position);
viewHolder.minusItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
order.productQuantity --;
if(order.productQuantity() <= 0){
order.productQuantity = 0;
notifyDataSetChanged();
}
Toast.makeText(getContext(),"" + order.productQuantity(),Toast.LENGTH_SHORT).show();
return convertView;
}
}
myProduct.java
public class myProduct implements Parcelable {
#SerializedName("productID")
public int productID;
#SerializedName("categoryID")
public int categoryID;
#SerializedName("productName")
public String productName;
#SerializedName("productPrice")
public int productPrice;
public int productQuantity = 0;
public myProduct(int productID, int categoryID, String productName, int productPrice){
this.productID = productID;
this.categoryID = categoryID;
this.productName = productName;
this.productPrice = productPrice;
}
public int getProductID(){
return productID;
}
public int getCategoryID(){
return categoryID;
}
public String getProductName(){
return productName;
}
public int getProductPrice(){
return productPrice;
}
public int productQuantity() {
return productQuantity;
}
protected myProduct(Parcel in) {
productID = in.readInt();
categoryID = in.readInt();
productName = in.readString();
productPrice = in.readInt();
productQuantity = in.readInt();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(productID);
dest.writeInt(categoryID);
dest.writeString(productName);
dest.writeInt(productPrice);
dest.writeInt(productQuantity);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<myProduct> CREATOR = new Parcelable.Creator<myProduct>() {
#Override
public myProduct createFromParcel(Parcel in) {
return new myProduct(in);
}
#Override
public myProduct[] newArray(int size) {
return new myProduct[size];
}
};
}
Menu.class
viewOrder = (Button)findViewById(R.id.viewOrder);
viewOrder.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(Menu.this, Order.class);
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("productList", productList);
i.putExtras(bundle);
startActivity(i);
}
});
Order.class
Bundle bundle = getIntent().getExtras();
productList = bundle.getParcelableArrayList("productList");
filter = new ArrayList<myProduct>();
orderAdapter = new myOrderAdapter(getApplicationContext(),filter);
for(myProduct item : productList){
if(item.productQuantity > 0){
Log.d(TAG,item.getProductName());
Log.d(TAG,"" + item.productQuantity());
filter.add(item);
}
else if(item.productQuantity <= 0){
filter.remove(item);
}
}
orderListView.setAdapter(orderAdapter);
The issue is that you are passing the array to the second adapter as a Parcelable, so it's basically making a deep copy of the array, and has nothing to do with the original array. Therefore changes in second array, don't show in first array.
A simple (but maybe dirty) solution would be to make the array as a static variable (or part of the application class, or a singleton), and use the actual array in both activities.
If you can design, that both lists are in two fragments, and part of one activity, then just have the activity hold on to the shared array for both fragments.

notifyDataSetChanged() doesn't work

i got this problem yesterday:
Here I have a list returned by server, and there is a Hashmap list(List) and a Hashmap inside the list.And I got two situations, one is when the hashmap list is null, I add a new item into it,and then call notifyDataSetChanged() doesn't work, and the other situation is when i changed the value in hashmap, and notifyDataSetChanged(), it doesn't refresh either.And I'm sure the data has been changed successfully.
it shows in A activity and changed data in B activity.
A activity:
protected List<CommentEntity> mDataList;
protected ListView mListView;
protected BaseListAdapter mAdapter;
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
int position = data.getIntExtra("position", -1);
if (position > -1) {
CommentEntity entity = (CommentEntity) data.getSerializableExtra(AppVars.Keys.EXTRA_ENTITY);
mDataList.set(position, entity); // I want this list update
mAdapter.notifyDataSetChanged();
} else {
// error
}
}
public class BaseListAdapter extends BaseAdapter {
#Override
public int getCount() {
return mDataList == null ? 0 : mDataList.size();
}
#Override
public Object getItem(int position) {
return mDataList == null ? null : mDataList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// actually this adapter is written in MyBaseFragment, and the child
// Fragment will override setupItemView() method.it's working fine
return setupItemView(position, convertView, parent);
}
}
B activity:
private CommentEntity mCommentEntity;
// the list below is inside CommentEntity, QuoteEntity is extends HashMap<>.
private List<QuoteEntity> mQuoteList;
private QuoteAdapter mAdapter;
public void update(QuoteEntity newQuote) {
mQuoteList.add(newQuote);
mCommentEntity.setReplyRows(mQuoteList);
mAdapter.notifyDataSetChanged();// This adapter is just working fine.
setResult(-1, getIntent().putExtra(AppVars.Keys.EXTRA_ENTITY, mCommentEntity));
}
Try resetting listview instead of using notifyDataSetChanged();
ListView lv = (ListView)FindViewById(R.id.lv);
BaseListAdapter aa = new BaseListAdapter(//constructor's parameters);
lv.setAdapter(aa);

Categories