Reusing the same ListView to display different data - android

ListViews have always been my weak point and right now I am practicing putting a Listview, within a Listview. Anyway, I first call my ListView at the start of my program and it loads it with an array saved in my strings.xml:
String[] departments = getResources().getStringArray(
R.array.departments_array);
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item,
departments));
setContentView(R.layout.main);
ListView lv = getListView();
lv.setTextFilterEnabled(true);
What I want to do is update this ListView with a new array of values each time a list item is clicked. The reason why I am trying to do it this way is because I plan on having 27 different arrays with different values for each position, and I feel it would be lighter on my resources if instead of making a ListView for each array of items, I would update this one ListView. I know I am probably not doing this the most efficient way, but if there is another way of implementing my idea please tell me.
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
switch (position) {
case 0:
try {
//It is here that i dont know what to do, I was going to call
//the Listview the same way i did previously using my setlistadapter,
//but i kept getting errors about the code being undefined
String[] listitems1 = getResources().getStringArray(
R.array.items_array);
} catch (ClassCastException e) {
Toast.makeText(getApplicationContext(), "Error",
Toast.LENGTH_SHORT).show();
}
break;
case 1:
try {
//The listview will be changed again here
} catch (ClassCastException e) {
Toast.makeText(getApplicationContext(), "Error",
Toast.LENGTH_SHORT).show();
}
break;
}
};
});

Have you thought of using a BaseAdapter and setting it as the list adapter
http://developer.android.com/reference/android/widget/BaseAdapter.html

Your approach is wrong( if I understand what are you doing). Instead of replacing the adapter of the ListView every time the user clicks(and simply setting a new adapter should work) a element in the initial list you should start a new activity passing the clicked position and in your new activity set the adapter on a ListView with the correct array based on that position.
A small example:
Main class:
/**
* The main class with the initial 27 items array.
*/
public class Class1 extends ListActivity {
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// start the second activity that will show our array depending on the
// position clicked
Intent i = new Intent(this, Class2.class);
// put the position in the Intent so we can know in the other activity
// what array to load.
i.putExtra("pos", position);
startActivity(i);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// I just used a simple array of 2 items, you'll load your 27 items
// array
String[] items = { "1", "2" };
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, items));
}
}
Secondary activity that will show the array based on the previously selected position:
public class Class2 extends ListActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// get the Intent that started the activity
Intent i = getIntent();
// find out what position did that other activity send to us.
int position = i.getIntExtra("pos", -1);
// load the ListView with an adapter based on the array that you
// want(according to that position)
if (position == 0) {
// the first element in the main list
String[] items = getResources().getStringArray(R.array.a1);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, items));
} else if (position == 1) {
// the second element in the main list
String[] items = getResources().getStringArray(R.array.a2);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, items));
} else {
// etc
}
}
}

Luksprog's answer is indeed correct, and it is very useful for lists many levels deep (you do not put limits, just keep spawning new activity instances with the proper list loaded)
BUT
If your list isn't more than 2 levels deep you can use ExpandableListActivity instead of ListActivity which is basically an enhanced version of the single-level list you're using which natively handle group collapsing/expanding and therefore you do not need the spawn of a new activity for each sublevel.
again note that this approach works only for lists which do not go deeper than 2 levels
ExpandableListActivity documentation
ExpandableListView documentation
ExpandableListAdapter documentation - you should be fine with the BaseExpandableListAdapter implementation
And here you have some nice example from Google itself:
public class ExpandableList3 extends ExpandableListActivity {
private static final String NAME = "NAME";
private static final String IS_EVEN = "IS_EVEN";
private ExpandableListAdapter mAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
List<Map<String, String>> groupData = new ArrayList<Map<String, String>>();
List<List<Map<String, String>>> childData = new ArrayList<List<Map<String, String>>>();
for (int i = 0; i < 20; i++) {
Map<String, String> curGroupMap = new HashMap<String, String>();
groupData.add(curGroupMap);
curGroupMap.put(NAME, "Group " + i);
curGroupMap.put(IS_EVEN, (i % 2 == 0) ? "This group is even" : "This group is odd");
//filling with dummy data...
List<Map<String, String>> children = new ArrayList<Map<String, String>>();
for (int j = 0; j < 15; j++) {
Map<String, String> curChildMap = new HashMap<String, String>();
children.add(curChildMap);
curChildMap.put(NAME, "Child " + j);
curChildMap.put(IS_EVEN, (j % 2 == 0) ? "This child is even" : "This child is odd");
}
childData.add(children);
}
// Set up our adapter
mAdapter = new SimpleExpandableListAdapter(
this,
groupData,
android.R.layout.simple_expandable_list_item_1,
new String[] { NAME, IS_EVEN },
new int[] { android.R.id.text1, android.R.id.text2 },
childData,
android.R.layout.simple_expandable_list_item_2,
new String[] { NAME, IS_EVEN },
new int[] { android.R.id.text1, android.R.id.text2 }
);
setListAdapter(mAdapter);
}
}

Related

How to remove item from ArrayList<HashMap<String, String>> one by one in android

I am new to Android. I am Using "com.devsmart.android.ui.HorizontalListView" to show my items(playing cards). In the List I am getting 8 cards in the first attempt. What I want if I again call the method the there must be 7 cards so on means 1 cards must be remove from the list at each time till the list gets empty. But I am not able not do this removing of item from the list. I am posting my code here. Help will be appreciated.
MainActivity.java
ArrayList<HashMap<String, String>> aList9;
Button btn_aditional_card;
HorizontalListView list1;
int[] cards3 = new int[]{
R.drawable.card1,
R.drawable.card1,
R.drawable.card1,
R.drawable.card1,
R.drawable.card1,
R.drawable.card1,
R.drawable.card1,
R.drawable.card1,
R.drawable.card1,
R.drawable.card1,
R.drawable.card1,
R.drawable.card1,
R.drawable.card1,
R.drawable.card1
};
public class MainActivity extends AppCompatActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_aditional_card = (Button) findViewById(R.id.btn_aditional_card);
list1 = (HorizontalListView) findViewById(R.id.listview1);
btn_aditional_card.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
add8();
}
});
}
public void add8() {
final android.view.animation.Animation animScale = AnimationUtils.loadAnimation(this, R.anim.slide_right_in);
list1.startAnimation(animScale);
aList9 = new ArrayList<HashMap<String, String>>();
for (int i = 0; i < 8; i++) {
HashMap<String, String> hm = new HashMap<String, String>();
hm.put("card", Integer.toString(cards3[i]));
aList9.add(hm);
}
String[] from = {"card"};
int[] to = {R.id.ImageView};
final SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), aList9, R.layout.activity_animation__adapter, from, to);
list1.setAdapter(adapter);
adapter.notifyDataSetChanged();
list1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
aList9.remove(aList9.size() - 1);
adapter.notifyDataSetChanged();
}
});
}
Here removing of item from the list must be done on list1.setOnItemClickListener but I don't have any idea how.
In your list1.setOnItemClickListener, do this:
if (aList9.size() > 0) {
aList9.remove(aList9.size() - 1);
adapter.notifyDataSetChanged();
}
When removing item from data list, you have to notify your adapter to update view.
You can remove the last item from the list like;
if (aList9.size() > 0) {
aList9.remove(aList9.size() - 1);
}
Another solution,
Take Length of your integer array and traverse the loop inside your add8 method according to this length and at the end of the method decrement the length by one, like;
int length = cards3.length;
Inside your add8 method;
for (int i = 0; i < length; i++) {
HashMap<String, String> hm = new HashMap<String, String>();
hm.put("card", Integer.toString(cards3[i]));
aList9.add(hm);
}
After for loop decrement the length like;
length--;
Hope you'll get the solution.
In your main activity the code should look like.I am using arraylist instead you can use hashmap.This code is only to show you way what you need to do. follow this code in your project you will get solution this is tested in my site and working fine you need to change somewhere according to your code.In button click i am only removing last item from arraylist and notifying that dataset changed.hope it will help you.
ArrayList<String> arrlist = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
arrlist.add("B");
arrlist.add("C");
arrlist.add("D");
arrlist.add("E");
arrlist.add("F");
arrlist.add("G");
ListView lv = (ListView) findViewById(R.id.listview);
Button btnShowList = (Button) findViewById(R.id.btnShowList);
final ArrayAdapter adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, arrlist);
//Listview adapter
lv.setAdapter(adapter);
btnShowList.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (arrlist.size() > 0) {
arrlist.remove(arrlist.size() - 1);
adapter.notifyDataSetChanged();
}
}
});
}
Read the comments
class MainActivity extends AppCompatActivity {
//make your Adapter global
private SimpleAdapter adapter;
ArrayList<HashMap<String, String>> aList9;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
add8();
btn_aditional_card.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// on button click you can add a view to the listview if you want
// if you don't want this just comment out the following line
// i still don't understand what you want to do with this button
alist9.add(...);
// if you add stuff in the array list then notify the adapter
// it will update the view
adapter.notifyDataSetChanged();
}
});
}
public void add8() {
// initialize your ArrayList and listview
//populate them
for(int i = 0; i < 8; i++) {
// do your stuff.
// populate the list
}
// initialize your adapter as before
adapter = new SimpleAdapter(....);
listview.setadapter(adapter);
adapter.notifyDataSetChanged();
list1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// delete the items like this
// check if size is greater than 0 and then remove
aList9.remove(aList9.size() - 1);
adapter.notifyDataSetChanged();
}
});
}
}

SectionIndexer interface does not update

I wanted to make a listview with alphabetical adapter so that you can see the letters mapped to each section when fastscrolling. The following works correctly when the listview is initialised. However, if the list changes (e.g. adding or removing rows) the indexer does not seem to update even though a new adapter is created each time. It uses the same set of alphabets as the original list.
private void GenerateListView (final ArrayList<String> listItems) {
try {
listView = (ListView) findViewById(R.id.listView_browser);
// generate section index adapter
AlphabeticalAdapter adapter = new AlphabeticalAdapter(this,
android.R.layout.simple_list_item_1, listItems);
listView.setAdapter(adapter);
// recall scroll position
if (_currPos < listItems.size())
listView.setVerticalScrollbarPosition(_currPos);
} catch (Exception e) {
e.printStackTrace();
}
}
The following is the alphabetical adapter class.
public class AlphabeticalAdapter extends ArrayAdapter<String> implements SectionIndexer
{
private HashMap<String, Integer> alphaIndexer;
private String[] sections;
public AlphabeticalAdapter(Context c, int resource, List<String> data)
{
// create ArrayAdapter<String>
super(c, resource, data);
// generate HashMap
alphaIndexer = new HashMap<>();
// generate index
for (int i = 0; i < data.size(); i++)
{
// convert first letter of each entry to upper case
String s = data.get(i).substring(0, 1).toUpperCase();
// map letter with corresponding index
if (!alphaIndexer.containsKey(s))
alphaIndexer.put(s, i);
}
// assign set view of keys in the HashMap
Set<String> sectionLetters = alphaIndexer.keySet();
// generate list from the set view
ArrayList<String> sectionList = new ArrayList<>(sectionLetters);
// sort list alphabetically
Collections.sort(sectionList);
// define and populate string array with the letters
sections = new String[sectionList.size()];
for (int i = 0; i < sectionList.size(); i++)
sections[i] = sectionList.get(i);
}
See this solution Code.
And to update SectionIndexer using filter or any data change override this method. It's work for me.
#Override
public void notifyDataSetInvalidated() {
//write your code
super.notifyDataSetInvalidated();
}

Using simple_list_item_2 and can't figure out how to use setOnItemClickListener

Please excuse me, I'm new:new at this. I use a simple_list_item_2 to display 11 items. These 11 items have been loaded by using HashMap and then SimpleAdapter. This works fine in displaying everything. The problem is that I cannot get setOnItemClickListener going. The code:
public class TwoLineActivity extends ListActivity
{
ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>(2);
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.scrolllist);
// enter valid data, these 2 are the same as the remaining 9
HashMap<String, String> maplist;
maplist = new HashMap<String, String>();
maplist.put("line1", "a11 data");
maplist.put("line2", "asd asd ad 1234569780");
list.add(maplist);
maplist = new HashMap<String, String>();
maplist.put("line1", "a12 data");
maplist.put("line2", "asd asd ad 1234569781");
list.add(maplist);
String[] from = { "line1", "line2" };
int[] to = { android.R.id.text1, android.R.id.text2 };
SimpleAdapter adapter = new SimpleAdapter(this, list, android.R.layout.simple_list_item_2, from, to);
setListAdapter(adapter);`
So up to here things are great, I get my list. Now I want to be able to select an item from the list, so I coded the next 2 lines
list.setAdapter(adapter);
list.setOnItemClickListener(new OnItemClickListener()
{ .....
I get the following errors
The method setAdapter(SimpleAdapter) is undefined for the type ArrayList<HashMap<String,String>>
and
The method setOnItemClickListener(new AdapterView.OnItemClickListener(){}) is undefined for the type ArrayList<HashMap<String,String>>
If your activity extends ListActivity, you should override
protected void onListItemClick(ListView l, View v, int position, long id) {
}

Android Tabbed application - List connected to Google Maps

I have the following in one of my tabs:
ListView list=(ListView)findViewById(R.id.countries);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, COUNTRIES);
list.setAdapter(adapter);
static final String[] COUNTRIES = new String[] {
"List Item 1", "List Item 2", "List Item 3" };
This list is within a tab. I want to change it so when one of the items is clicked (say we call it London Big Ben, I want to somehow attach co-ordinates to that) it diverts to Google Maps either via WebView (easiest) or MapView appears over the tab (but the tab bar is still visible).
Can anyone provide links to tutorials or assistance?
This is the code where i am put my data inside arraylist which i am fetching from Web Service.
public static ArrayList<HashMap<String, String>> mylist;
for (int i = 0; i < nodes.getLength(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
map.put("Name",name);
map.put("Vicinity", vicinity);
map.put("Latitude", lat);
map.put("Longitude", lng);
mylist.add(map);
}
After this below is the code of ListView Activity class. Where i have implemented on click listner and on click of listview calling another activity and passing the position of the list which is clicked.
ListViewActivity Class code
public class ListViewActivity extends ListActivity implements OnItemClickListener{
private ListView lv;
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.listingatms);
ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.listdata,
new String[] {"Name", "Vicinity"},
new int[] { R.id.item_title, R.id.item_subtitle});
setListAdapter(adapter);
lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {
// TODO Auto-generated method stub
Intent showMapMenusIntent = new Intent(ListViewActivity.this, MapMenus.class);
showMapMenusIntent.putExtra("Position", position);
startActivity(showMapMenusIntent);
}
If you want to show the map in the same activity then use the postion variable and on the basis of that you can get all the values from mylist(ArrayList).
For e.g position = mylist.get(position).get("Name"));
This way you will be able to get all the details from ArrayList and use it as per your requirement.
Hope this will help you...

repeating ListView

Hey guys I am a working on displaying a list of items on listview, the code I am using is
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom_list_view);
ListView lv= (ListView)findViewById(R.id.listview);
rtrnList = new ArrayList<HashMap<String,String>>();
getmyLocation();
listclass = new listClass(offersobj);
listclass.populate();
rtrnList = listclass.getListArray();
adapter = new SimpleAdapter(
this,
rtrnList,
R.layout.custom_row_view,
new String[] {"Name","Msg","time"},
new int[] {R.id.text1,R.id.text2, R.id.text3}
);
lv.setAdapter(adapter);
}
problem is say I am displaying three names Avinash, Arun, Rajesh. When application starts these three names are displayed on list. When I close and again start the application the values are repeating Avinash, Arun, Rajesh,Avinash, Arun, Rajesh. I am not able to figure out how to solve this.
The code you show seems fine. My guess is that listclass.populate() modifies offersobj and that offersobj is reused over several creations of your activity. So, whenever the activity is created, additional data is populated.
public class ListViewA extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView lv= (ListView)findViewById(R.id.listview);
// create the grid item mapping
String[] from = new String[] {"rowid", "col_1", "col_2", "col_3"};
int[] to = new int[] { R.id.item1, R.id.item2, R.id.item3, R.id.item4 };
// prepare the list of all records
List<HashMap<String, String>> fillMaps = new ArrayList<HashMap<String, String>>();
for(int i = 0; i < 10; i++){
HashMap<String, String> map = new HashMap<String, String>();
map.put("rowid", "" + i);
map.put("col_1", "col_1_item_" + i);
map.put("col_2", "col_2_item_" + i);
map.put("col_3", "col_3_item_" + i);
fillMaps.add(map);
}
// fill in the grid_item layout
SimpleAdapter adapter = new SimpleAdapter(this, fillMaps, R.layout.grid_item, from, to);
lv.setAdapter(adapter);
}
}
for more example see this linkthis alsolistview about adapter, for create a hashmap, why bitmap type imported cannot show image in listview?What adapter shall I use to use HashMap in a ListView

Categories

Resources