How to create nested listview with searchbar in android toolbar? - java

I tried this code and doesn`t return my inputed text.
This is my Addtocartitems.java :
This is my Downloadeditems.java :
This is my DownloadedListAdapter2.java :
This program has no error but nothings happened.
Can anybody help me please? Thanks in advance!

Create the list variavble in adapter class
List<DownloadedItems> downloadedItemsList= new ArrayList<>();
inside your constructor please call write down this
public DownloadListAdapter(Context context, int resource, ArrayList<DownloadedItems> object){
super(context,resource,object);
this.mcontext= context;
this.mResource=resource;
this.downloadedItemsList= object;
}
create the method in adapter which gets the list
public void setData(List<DownloadedItems> modelList) {
this.downloadedItemsList= modelList;
notifyDataSetChanged();
}
Now call the filter method with new filtered list and pass that list to adapter method
private void filter(String text) {
List<DownloadedItems> filteredList = new ArrayList<DownloadedItems>();
for (DownloadedItems la :langList) {
if (la.langName.toLowerCase().startsWith(text.toLowerCase())) {
filteredList.add(la);
}
adapter.setData(filteredList);
}
}
You can change the method .startsWith to .Contains as of your requirement. This method returns the items which starts with the entered string. langList is the initial list which i have passed already to the adapter to present.
la.langName.toLowerCase().startsWith
this is the filter query , the item which i am using to compare to filter. I am searching the language name from the list. So you can modify according to your requirement.and call the method filter from
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
filter(newText)
return true;
}
});

Related

Android AutoCompleteTextView It's not displaying the provided list correctly

I'm building a chat app where users can mention each other by typing the '#' symbol followed by a username. I'm using an AutoCompleteTextView to show a list of suggested usernames as the user types. I'm populating the adapter for the AutoCompleteTextView by implementing a callback interface in my activity and using the resulting list of usernames to create an ArrayAdapter.
I want the AutoCompleteTextView to only show suggestions when the user is typing the '#' symbol, so I've added some code to check for the presence of the '#' character and set the dropdown height of the AutoCompleteTextView accordingly.
However, when I start typing a username and the filter is applied to the ArrayAdapter, I'm getting only a part of the full list of usernames, but multiple times. I suspect that the issue is in the performFiltering method of the ArrayAdapter, where I'm iterating over the full list of usernames and adding them to the suggestions list if they meet certain conditions.
Can anyone help me figure out why I'm getting duplicates in my AutoCompleteTextView suggestions and how I can fix this issue?
so this is my code
in my activity I implement the interface:
implements ChatViewModel.Callback
And getting the callback like this:
#Override
public void onComplete(List<String> result) {
MentionAdapter mentionAdapter = new MentionAdapter(ChatActivity.this, result);
binding.chatEtText.setAdapter(mentionAdapter);
}
And I'm calling it right away in the onCreate:
chatViewModel.getLiveMentionChannelsSearch();
But I only want that the AutoComplete should show up when a user is pressing the "#"character. So I did this:
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String mention = binding.chatEtText.getText().toString().toLowerCase();
if (!binding.chatEtText.getText().toString().contains("#") ){
binding.chatEtText.setDropDownHeight(0);
}else {
binding.chatEtText.setDropDownHeight(500);
}
And in the ArrayAdapter I am doing this:
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
List<String> suggestions = new ArrayList<>();
String filterPattern = constraint.toString().toLowerCase().trim();
for(String item:MentionItemsFull){
if (filterPattern.length() >1) {
charAtZero =Character.toString(filterPattern.charAt(1));
}
if (filterPattern.startsWith("#")){
suggestions.addAll(MentionItemsFull);
}
if (charAtZero != null && item.toLowerCase().startsWith(charAtZero) ){
suggestions.add(item);
}
if (filterPattern.contains(" ")){
suggestions.clear();
}
}
results.values = suggestions;
results.count = suggestions.size();
return results;
}
The MentionItemsFull is the full list without any filter from the constructor.
private List<String> MentionItemsFull;
public MentionAdapter(#NonNull Context context, List<String> MentionItemList) {
super(context, 0, MentionItemList);
MentionItemsFull = new ArrayList<>(MentionItemList);
}
But the problem is that, when I am pressing the "#" character, I am getting only a part of the full list but multiple times.
Anyone know why?

DiffUtil not calling onBindView or refreshing ViewHolder

I tried to use DiffUtil approach to update my list which always consist of 30 items, now each item data updates every minute but no way of telling if all item's data will have updates so to avoid abusing notifyDataSetChanged() I create a class extending DiffUtil.
public class DifUtil extends DiffUtil.Callback {
private final List<Asset> oldList, newList;
public DifUtil(List<Asset> newList, List<Asset> oldList) {
this.oldList = oldList;
this.newList = newList;
}
#Override
public int getOldListSize() {
return oldList.size();
}
#Override
public int getNewListSize() {
return newList.size();
}
#Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return oldList.get(oldItemPosition).getId().equals(newList.get(newItemPosition).getId());
}
#Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return oldList.get(oldItemPosition).equals(newList.get(newItemPosition));
}
#Nullable
#Override
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
//you can return particular field for changed item.
return super.getChangePayload(oldItemPosition, newItemPosition);
}
}
Add new public function to notify the adapter with this
public void updateList(List<Asset> newList) {
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DifUtil(newList, this.assetList));
this.assetList.clear();
this.assetList.addAll(newList);
diffResult.dispatchUpdatesTo(this);
}
Overriding another onBindViewHolder (not sure if needed when not using payload)
onBindViewHolder(#NonNull AssetsAdapter.ViewHolder holder, int position, #NonNull List<Object> payloads)
Then updating the list by just calling
adapter.updateList(newAssetList);
The updating of list works but I can only see those new values by scrolling the list, I need to view the updates even without recycling the view (when scrolling) just like notifyItemChanged().
To my understanding calling dispatchUpdatesTo should handle and update the views and its data or am I missing something here please enlighten me.
I managed to make it work by following this blog and its way of implementing DiffUtil.
https://www.journaldev.com/20873/android-recyclerview-diffutil
However I did not perform the cloning part since it is irrelevant on my case.
BONUS
There is a known bug where updates makes the list to scroll at the bottom. I get rid of this by saving scroll state with LayoutManager like in this SO answer.
https://stackoverflow.com/a/44053550/11338467
So my adapter DiffUtil update part will be this
public void updateList(List<Asset> newList) {
Parcelable recyclerViewState = layoutManager.onSaveInstanceState();
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DifUtil(newList, this.assetList));
diffResult.dispatchUpdatesTo(this);
this.assetList.clear();
this.assetList.addAll(newList);
layoutManager.onRestoreInstanceState(recyclerViewState);
}

Search an ArrayList Model

I want to get all items that contains the search input based on itemName. In c#, I can use lambda, but I could not find any references for android.
Here is the model class:
public class ModelItem {
public long itemId;
public String itemName;
public double price;
}
Here is my list:
public static ArrayList<ModelItem> items;
I will use the list to get the items. Thank you in advance.
Use below code
public void getAllItems(ArrayList<ModelItem> items, String searchItem) {
for(ModelItem item : items) {
if(item.getItemName().contains(searchItem)) {
// here you are getting item which matches inside your list
}
}
I think you have a listview with items. Now you want to filter them with a search string.
You have to implement Filterable in your custom adapter.
How to filter an adapter
First step, copy items into tempList
private ArrayList<ModelItem> items; // You have data into this list
private ArrayList<ModelItem> tempData = new ArrayList<>();
for (ModelItem item : items) {
tempData.add(item);
}
This is to filter items based on query
public void filter(String query) {
items.clear();
if (query.length() > 0) {
for (ModelItem currItem : tempData) {
// Add data into list, if item is having query string
if (currItem.getItemName().toLowerCase().contains(query)) {
mData.add(currItem);
}
}
} else {
// Adding all the items, if query is empty
for (ModelItem item : tempData) {
items.add(item);
}
}
notifyDataSetChanged(); // notify the changes, if you are using an adapter.
}
hey i got a example for your requirement in github, you need to use QueryTextListener in main class, then setFilter to adapter as given in example
please check this link:https://github.com/Wrdlbrnft/Searchable-RecyclerView-Demo

jList not displaying data in specific case

In my program, I have a jList and I can add, delete, modify items in this Jlist.
My problem is, if I click on my add button before selecting an item in my jList, the items inside the jList disapear. (only in apeareance because they are actually still in the jList)
If, before that, I select an item in my list, then everything is working fine. So my guess would be that the "valueChanged()" method from my listener is doing something that I don't do myself.
Here is my list initialisation, which I call at the start of the program:
public final void initList() {
jListPaiement.setModel(new MyListModel(ls.getDb().getListePaiements()));
final DecimalFormat df = new DecimalFormat("###.##");
jListPaiement.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent lse) {
MoyenPaiement mp = (MoyenPaiement) ((MyListModel) jListPaiement.getModel()).getElementAt(jListPaiement.getSelectedIndex());
jTextFieldFF.setText(df.format(mp.getFraisf()));
jTextFieldFV.setText(df.format(mp.getFraisv() * 100));
jTextFieldNomP.setText(mp.getNom());
jTextFieldFF.setVisible(true);
jTextFieldFV.setVisible(true);
jTextFieldNomP.setVisible(true);
jLabel1.setVisible(true);
jLabel6.setVisible(true);
jLabel7.setVisible(true);
jLabel8.setVisible(true);
jLabel11.setVisible(true);
jButtonSaveP.setVisible(true);
}
});
Here is the code from the add button:
private void jButtonAddPActionPerformed(java.awt.event.ActionEvent evt) {
MoyenPaiement mp = new MoyenPaiement("Nouveau", 0, 0);
((MyListModel) jListPaiement.getModel()).addElement(mp);
jListPaiement.setSelectedValue(mp, true);
jListPaiement.repaint();
}
MyListModel code:
public class MyListModel extends AbstractListModel {
ArrayList list;
public MyListModel(ArrayList list) {
this.list = list;
}
#Override
public int getSize() {
return list.size();
}
#Override
public Object getElementAt(int i) {
return list.get(i);
}
public void addElement(Object o){
list.add(o);
}
public void deleteElement(Object o){
list.remove(o);
}
public void setElement(int i,Object o){
list.set(i, o);
}
public ArrayList getList() {
return list;
}
public void setList(ArrayList list) {
this.list = list;
}
}
Any help will be greatly appreciated.
Thanks
Edit: After further research, the problem is when I add item to my model.
It comes exactly on the line:
((MyListModel) jListPaiement.getModel()).addElement(mp);
Even if I add a simple string such as:
((MyListModel) jListPaiement.getModel()).addElement("String");
The problem still occurs.
Look in detail what happens on this line and if you initialize jListPaiement correctly with the right data.
jListPaiement.setModel(new MyListModel(ls.getDb().getListePaiements()));
Seems like on this line setSelectedValue() can't find the element mp
jListPaiement.setSelectedValue(mp, true);
I finally found a solution.
Rather than using my own List Model, I used DefaultListModel and everything works fine. It's been long time since i worked on this project and I don't remember why i chose to make my own list model class.
Even tough it works now, I still don't understand what was missing in my own class (MyListModel) that made it not working..

ArrayAdapter contains an object based on a value

I have a ListView and ListView adapter. I am adding objects to the adapter but I only want to add one row with an object that contains a certain String. This is my code but it does not work:
public static List<FriendsVideoLVModel> list = new ArrayList<FriendsVideoLVModel>();
#Override
public void add(FriendsVideoLVModel obj) {
super.add(obj);
for (int i=0; i <list.size(); i++) {
if (!obj.eventTitle.equals(list.get(i).eventTitle)) {
list.add(obj);
notifyDataSetChanged();
}
}
}
Please help. The logic looks fine to me but it just does not work. Nothing is in fact added.

Categories

Resources