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.
Related
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
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..
I have an array: Object[] array, and an array adapter that extends ArrayAdapter<Object>.
When i try to delete from it using adapter.remove(Object obj) i get an UnsupportedOperationException exception, just as this post.
The provided answers suggest using an ArrayList instead. This is not an option for me. I need to stick with array. So i copied the array to another array, but without the item i want to delete. Then i just did:
oldArray = newArray;
and then called adapter.notifyDataSetChanged();.
This works fine except it doesn't refresh the screen. I need to close then reopen the screen to see the changes. Shouldn't notifyDataSetChanged() do the refreshing?
edit:
Following #MD's answer, this is what i'm doing right now:
controller.onRemove(id);
public void onRemove(int id) {
int userListLength = usersArray.length;
int j = 0;
User[] newUserList = new User[userListLength-1];
for(int i=0; i<userListLength; i++)
{
if(id != usersArray[i].getId())
{
newUserList[j] = new User();
newUserList[j] = usersArray[i];
j++;
}
}
usersArray = newUserList;
//store in database
//...
view.getAdapter().refresh( usersArray );
}
public void refresh(User[] items)
{
this.userArray = items;
notifyDataSetChanged();
}
adapter construction:
adapter = new myUserAdapter( controller.getBaseContext(), R.layout.user_row, userArrayList);
usersListView.setAdapter( adapter );
and in myUserAdapter i have:
private User[] userArray;
Solution:
#MD's answer works. But I also had to override getCount() in the adapter:
#Override
public int getCount () {
return userArray.length;
}
It's explained in the accepted answer here.
i have a way
Add refresh method in your adapter:
public void refresh(List<String> items)
{
this.items = items;
notifyDataSetChanged();
}
and call from Activity like
yourAdapter.refresh(items); // items new arrayList or Array
ArrayAdapter simply wraps the List<T> you pass to its constructor and when you call remove(), it calls the remove() method of that list.
If you pass an array instead of a list to the constructor, it converts it with Arrays.asList().
/**
* Constructor
*
* #param context The current context.
* #param resource The resource ID for a layout file containing a TextView to use when
* instantiating views.
* #param objects The objects to represent in the ListView.
*/
public ArrayAdapter(Context context, int resource, T[] objects) {
init(context, resource, 0, Arrays.asList(objects));
}
In older Android versions Arrays.asList returns a readonly list. That's why you get the exception
You must explicitly create an ArrayList out of your array:
adapter = new myUserAdapter( controller.getBaseContext(), R.layout.user_row, new ArrayList<User>(Arrays.asList(userArrayList)));
I have a ListView with a custom ArrayAdapter with a custom object. The ListView contains headers. I loop through to get the header names on my custom objects. Some of them have the SAME value for headerTitle. I do NOT want them to get added to the row if that header already exists. This is my code (in my ArrayAdapter) to try and see if the same header has been added but it does absolutely nothing:
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();
}
}
}
Currently I am able to populate my spinner two ways one way gives me results from the database which is what I need but the text in the spinner is in JSON format, it all works but it looks bad, then if I extract the name from the JSON and use it I lose the value part of the name value pair.
I’ve been informed that I need to use a BaseAdapter subclass to be able to do what I need to do. The code below works just like I would love it to but the data is hard coded in, which is no use.
What I want to do is fill MyData below with the JSON data returned from the database.
This code:
final MyData items[] = new MyData[4];
items[0] = new MyData( "Ken's Plimbing","125738468");
items[1] = new MyData( "Peninsula Pests","3787906453");
items[2] = new MyData( "Joe's Electrical","129754354");
items[3] = new MyData( "Garderning Supplies","097803452");*/
ArrayAdapter<MyData> adapter = new ArrayAdapter<MyData>(PropertyManagement.this, android.R.layout.simple_spinner_item, items );
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
userSpinner.setAdapter(adapter);
userSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
MyData d = items[position];
Toast.makeText(PropertyManagement.this, d.getValue(), Toast.LENGTH_SHORT).show();
}
public void onNothingSelected(AdapterView<?> parent) {
}
}
);
With this BaseAdapter:
class MyData {
public MyData( String spinnerText, String value ) {
this.spinnerText = spinnerText;
this.value = value;
}
public String getSpinnerText() {
return spinnerText;
}
public String getValue() {
return value;
}
public String toString() {
return spinnerText;
}
String spinnerText;
String value;
Works!
But I need to fill MyData with the JSON array returned from the database. I have been doing that with the following as per the first paragraph in this post.
ArrayAdapter<String> adapter = new ArrayAdapter<String>(PropertyManagement.this, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
final MyData items[] = new MyData[4];
for (int i = 0; i < myUsers.length(); ++i)
{
adapter.add(myUsers.getJSONObject(i).getString("BusinessName"));
};
userSpinner.setAdapter(adapter);
The JSONArray/string looks like this,
{"BusinessName":"Petes Plumbing","BusinessPhone":"0434943743"},{"BusinessName":"Joes Electrical","BusinessPhone":"0466367279"}
Any help would be greatly appreciated.
Cheers,
Mike.
You are super close here, instead of adapter.add in your for loop you need to add it to items. Refactor like this:
final MyData items[] = new MyData[myUsers.length()];
for (int i = 0; i < MyData.length(); ++i){
items[i] = new MyData(myUsers.getJSONObject(i).getString("BusinessName"), myUsers.getJSONObject(i).getString("BusinessPhone"));
}
ArrayAdapter<MyData> adapter = new ArrayAdapter<MyData>(PropertyManagement.this, android.R.layout.simple_spinner_item, items );
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
userSpinner.setAdapter(adapter);
What is different here is your finding the length of your JSONArray, creating a new array of MyItem of that size. Then you initialize the items with new MyItems based on values from your JSONArray. Finally, you are creating the adapter with items just like you did in the first example. I'm assuming in this example that myUsers in a JSONArray.