Android : loop through all items in a listview - android

Want to get quick answer how to list all items on my listview, in order to print out a list or share to a notepad app etc. That is, to get a variable with following information from the listview: "apple", "banana", "orange". Below is my listview. Thanks
String[] values = new String[] { "apple", "banana", "orange" };
listItems = new ArrayList<String>();
for (int i = 0; i < values.length; ++i) {
listItems.add(values[i]);
}
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1,
listItems);
// Assign adapter to ListView
listView.setAdapter(adapter);

Your question says,
Loop through all items in a listview.
I understand from your code that you want to add the items from String array to ArrayList.
But, you can pass String array directly as a third parameter to your ArrayAdapter.
Look at the suggestions provided by Android studio for ArrayAdapter. You can pass String[] or ArrayList too :
Either you can pass String[] or if you wanted to loop through all String[] items to ArrayList, you can simply do by a single line.
Collections.addAll(arrayList,values);
arrayList - ArrayList
values - String[]
instead of,
listItems = new ArrayList<String>();
for (int i = 0; i < values.length; ++i) {
listItems.add(values[i]);
}
And in comment section, you said
I think I may add/remove item at a time to the listView later.
In this case, you can have some button to reload the list to show the old items + added new items or to show the list except the items which you've deleted. I'll add below how you have to achieve it.
Have a button AddMore in your layout and whenever you want to add new items, then do like this
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
arrayList.add("lemon"); // this adds item lemon to arraylist
arrayList.add("Pomgranete");
arrayAdapter.notifyDataSetChanged(); // this will refresh the listview and shows the newly added items too
}
});
You can delete the item similarly by passing the position of the item in arrayList,
arrayList.remove(arrayList.get(i)); // i is the position & note arrayList starts from 0
So, by summing up everything, here's the full working code :
public class MainActivity extends AppCompatActivity {
ListView listView;
String[] values = {"Apple", "Orange", "Banana"};
List<String> arrayList;
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView)findViewById(R.id.listView);
button = (Button)findViewById(R.id.button);
arrayList = new ArrayList<String>();
Collections.addAll(arrayList,values); // here you're copying all items from String[] to ArrayList
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,arrayList);
listView.setAdapter(arrayAdapter);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
arrayList.remove(arrayList.get(2)); // here i remove banana since it's position is two. My ordering of items is different so it removed banana. If i use ordering from your quest, it will remove orange.
arrayList.add("lemon"); // adding lemon to list
arrayList.add("Pomgranete"); // adding pomgranete
arrayAdapter.notifyDataSetChanged(); // this used to refresh the listView
}
});
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" tools:context=".MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ADD MORE"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="#+id/button" />
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_above="#+id/button" />
</RelativeLayout>
Output :
List with pre-defined 3 items and one button to load more items.
List with old 3 items + newly added 2 items (Here i didn't use arrayList.remove)
List with old items except deleted item + newly added 2 items (Here i used arrayList.remove to remove banana by arrayList.remove(arrayList.get(2));)

As I understand you want to create an ArrayAdapter, later add a few items to it and at some point retrieve all items from it, right?
Since you use ArrayAdapter you can just iterate over its content:
String[] items = new String[adapter.getCount()];
for(int i = 0; i < adapter.getCount(); i++){
items[i] = adapter.getItem(i);
Log.d("TAG", "Item nr: " +i + " "+ adapter.getItem(i));
}
ArrayAdapter documentation

Since you already have an array AND an arraylist in your code it should be easy.
But if you want to loop later and you have only your listview, I believe there is a getter for the adapter in your listview, and if you cast the given adapter to ArrayAdapter, it should then have a getter to the the items you are looking for.
ArrayAdapter<String> adapter = (ArrayAdapter<String>)mListView.getAdapter();
for(int i=0; i<adapter.getCount();i++){
String item = adapter.getItem(i);
/*...*/
}

You don't need to loop or anything just pass the array directly to the adapter.
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1,
values);
the new ArrayAdapter took an array as a third parameter.

Related

How to implement 2 different lists with 2 different ITEMS in a single listView with a sectional divider between the listView?

I want to implement a listView with 2 different lists which is using 2 different Items and want to display them using a same ListView.
Both lists are separated with a sectional divider
The above listView is having a custom selector imageButton in the item
below listView has dateDividers for their items
You should use
https://github.com/commonsguy/cwac-merge
in order to create and merge different adapters with the data you need. You should also insert a header view.
Here follows an example:
#BindView(R.id.lv_validation_errors)
ListView lvValidationErrors;
private List<Notification> notificationList = new ArrayList<>();
public MergeAdapter mergeAdapter = new MergeAdapter();
public ArrayAdapter errorAdapter;
private ArrayList<String> errorList = new ArrayList<>();
public ArrayAdapter alertAdapter;
private ArrayList<String> alertList = new ArrayList<>();
First I set the ListView (using ButterKnife, which does the findViewById stuff) then
errorAdapter = new ArrayAdapter(this, R.layout.adapter_error, R.id.text1, errorList);
mergeAdapter.addView(header("Erros"), false);
mergeAdapter.addAdapter(errorAdapter);
I created the adapters I want to mmerge and added the view for the section header (dont forget to set a value to your list to prevent it from being null) then
alertAdapter = new ArrayAdapter(this, R.layout.adapter_warning, R.id.text1, alertList);
mergeAdapter.addView(header("AdvertĂȘncias"), false);
mergeAdapter.addAdapter(alertAdapter);
same as the previous step and finally:
lvValidationErrors.setAdapter(mergeAdapter);
to set the merged adapter to the ListView.
for that you have to take one list with type Object
List<Object> listItems = new ArrayList<>();
your both different list values add in above listItems .
then after bind your adapter with listItems and when you bind your item in your BindView() write like below.
if(listItems instanceof firstListItemModel)
// bind item from your first list
else if(listItems instanceof secondListItemModel)
// bind item from your second list
As i can understand, you want a vertically half divided screen with containing ListView in each of them.
And you are saying that bottom ListView is completely based on upper ListView.
bottom ListView should load according to Upper ListView selection.
if Yes, then you can use weight to show bothListViews(upper and bottom) on layout like this :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp">
<ListView
android:id="#+id/list_view1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<ListView
android:id="#+id/list_view2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
Then you can take set Adapter on list_view2 on list_view1 item click :
ListView upperListView=(ListView) findViewById(R.id.list_view1);
ListView bottomListView=(ListView) findViewById(R.id.list_view2);
upperListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
// You can put your logic here to fetch data according to upper ListView item clicked position. I am taking temp. data for now.
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, arrayList//your desired list here);
((ListView) bottomListView.setAdapter(adapter);
}
});
That's it!!

updating Listview when sqlite updated

Hi guys is it possible that everytime I add an item in the database it will notify and update the listview? For example I have two fragments in one activity then When I send a data in the database from the Fragment A the Listview in Fragment B will update also without using interface.
There is a function of ArrayAdapter called - notifyDataSetChanged()
//getting the list view
ListView userListView = (ListView) findViewById(R.id.users_ListView);
//creating an array to represnt what ever you want
ArrayList<String> users = new ArrayList<>();
for (int i = 0; i < 10 ; i++) {
//populate the array
String s = "user " + i;
users.add(s);
}
//setting up adapter to the array (this is 1 row with 3 arguments)
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(),
android.R.layout.simple_list_item_1,
users);
//connecting the list view to get the data to show from the adapter
userListView.setAdapter(adapter);
//changing the arrayList by adding or subtracting
String s = "another user";
users.add(s);
//update the adapter and list view with this command
adapter.notifyDataSetChanged();
Share your code if you are having any trouble.
good luck =)

delete selected list items

I have an array string that i used in my Fragment,and i show the array string items with setListAdapter in my list:
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
String[] array = getResources().getStringArray(R.array.examlearray);
final ArrayList<String> str = new ArrayList<String>(Arrays.asList(array));
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1, str );
setListAdapter(arrayAdapter);
final ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {...
and under my onActionItemClicked i want to implement my deleteSelectedItem() method,that delete selected list items,and this my code,but it didn't remove selected item,it is just remove from first of list,and when i select all the items and press remove,the app crash!what should do?,Any help would be appreciated! Thanks!
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// Respond to clicks on the actions in the CAB
switch (item.getItemId()) {
case R.id.delete:
// deleteSelectedItems();
Log.i(TAG, "deleteSelectedEntries");
SparseBooleanArray checkedItems = listView.getCheckedItemPositions();
for(int i=0;i<checkedItems.size();++i)
{ if(checkedItems.valueAt(i))
str.remove(i);
}
arrayAdapter.notifyDataSetChanged();
Instead of looping through the SparseBooleanArray you get from listView.getCheckedItemPositions(), you have to loop through the items of the ArrayAdapter and then check if the SparseBooleanArray returns true for this item. This is because when you remove items from the ArrayAdapter, listView.getCheckedItemPositions() still returns items that don't exist anymore.
So in your case:
SparseBooleanArray checkedItems = listView.getCheckedItemPositions();
// Loop backwards, so you can remove the items from within the loop
for (int i = arrayAdapter.getCount() - 1; i >= 0; i--) {
if (checkedItems.get(i)) {
// This item is checked and can be removed
arrayAdapter.remove(arrayAdapter.getItem(i));
}
}
The reason your app crashed is because you try to remove non existing items.
You will need to hold a reference to your array adapter. Then try calling the remove function on the adapter followed by notifyDataSetChanged. If you only have a reference to the position, you will also need to use getItem.
Keep the reference of adapter and data list used for creating adapter, Its better to use ArrayList, since it gives flexibility to remove elements easily. To set the adapter you can use following code -
String[] array = getResources().getStringArray(R.array.examlearray);
ArrayList<String> str = new ArrayList<String>(Arrays.asList(array));
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1, str );
menuListView.setAdapter(arrayAdapter);
To remove element first remove the element from the data list and then calling notifyDatasetChnaged will update the listView as well. you can call following code inside onActionItemClicked
`for(int i=0;i<checkedItems.size();++i)
{ if(checkedItems.valueAt(i))
str.remove(i);
}
arrayAdapter.notifyDataSetChanged();

Updating crossed-out items on loading ListView

I am fairly new to Android programming and trying to set items in a listview upon loading the information from internal storage.
I have two global arrays that I am using: first one is a String array that has the names of the items in the list, and the second is a boolean array that keeps track of which items are crossed out. I am using a TextView in the listview.
main_activity.xml:
<ListView
android:id="#+id/listViewMyList"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
rowlayout.xml:
<TextView
android:id="#+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginBottom="3dp"
android:text="#+id/label" />
I have created an onClickListener() which successfully updates the state of each list item:
public class MainActivity extends Activity
{
// Initialize the list (global list values)
String[] values = new String[0]; // array of items for the list
boolean[] checkedVals = new boolean[0]; // keep track of which items are crossed-off
String localFileName = "myListData.csv";
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// read the data from file if present
readListFromFile();
// find the ListView
ListView lst = (ListView) findViewById(R.id.listViewMyList);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
R.layout.rowlayout, R.id.label, values);
lst.setAdapter(adapter);
// define what happens on click
lst.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view,int position, long id)
{
// read crossed status and set text flags for strikethrough
if (checkedVals[position])
{
TextView text1 = (TextView)view.findViewById(R.id.label);
text1.setPaintFlags(text1.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
text1.setTextColor(0xff000000);
checkedVals[position] = false;
}
else
{
TextView text1 = (TextView)view.findViewById(R.id.label);
text1.setPaintFlags(text1.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
text1.setTextColor(0xff888888);
checkedVals[position] = true;
}
// save the data in a file
saveListToFile();
}
});
}
So this code works fine for crossing out and un-crossing out the items. I don't know how can I cross-out some of the items (determined by the checkedVals boolean array) without clicking or any activity when I load the list.
Thanks in advance.
You need to create a custom Adapter by extending ArrayAdapter and overriding getView().
The getView() method loads every row's layout, this is where you should check if the row is in your checkedVals array and draw with the appropriate flags. This Google Talk by an Android lead programmer, Romain Guy, provide a wealth of information about best practices on how to do this.

How to fill a ListView with a string-array?

I want to show these itens at my ListView
<string-array name="bookmark_titles">
<item>Google</item>
<item>Bing</item>
<item>Gmail</item>
</string-array>
I have a method that gets these values.
public static Collection getBookmarks(Context context) {
Collection bookmarks = new Collection();
String[] titles = context.getResources().getStringArray(R.array.bookmark_titles);
for (int i = 0; i < titles.length; i ++) {
bookmarks.add(titles[i]);
}
return bookmarks;
}
How can I call the method getBookmarks in my main.java to fill the ListView?
I have already created a ListView. It is:
<ListView
android:id="#+id/my_listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#ECECEC"
android:dividerHeight="1sp" />
main.java
I am trying to do something like this:
ListView lv = (ListView) findViewById(R.id.my_listView);
ArrayList<Bookmark> my_array = BookmarkCollection.getTestBookmarks(context);
adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, my_array);
lv.setAdapter(adapter);
You can create your adapter with a one liner, check out the static method ArrayAdapter createFromResource(Context context, int textArrayResId, int textViewResId)
The first argument will probably be your Activity, the second is R.array.bookmark_titles, and the third is a layout to use.
To clarify based on the comments, the method accepts int, which is exactly what the constants in your generated R class are stored as.
Here's a complete example, assuming this is being called from an Activity:
ArrayAdapter<CharSequence> aa = ArrayAdapter.createFromResource(this, R.array.bookmark_titles, android.R.layout.simple_list_item_1);
myListView.setAdapter(aa);
In this case, android.R.layout.simple_list_item_1 refers to an XML layout that is provided by the Android SDK. You can change this if needed.
You can do this with an ArrayAdapter and have it use either an Array or a List to give it data
lv.setAdatper(new ArrayAdapter<String>(context, R.layout.some_layout_to_use, R.id.some_textview_in_layout, listData);

Categories

Resources