I am attempting to pass selected items on a list to a new activity.
I declared an ArrayAdapter
ArrayAdapter madapter
Before OnCreate; in OnResume, I collect the data; and assign it to mAdapter
//variable mAdapter
//new ArrayAdapter string
madapter = new ArrayAdapter<String>(
SearchingMidwife.this,
android.R.layout.simple_list_item_checked,
locations);
//set List to display mAdapter
And then I have this, that should allow for, when a listItem is clicked, to get selected items into a variable, and pass it to a new activity
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
//in checked, in listview get Item positions for checked items
SparseBooleanArray checked = l.getCheckedItemPositions();
//assign selected items to new String ArrayList
ArrayList<String> selectedItems = new ArrayList<String>();
//determine size of items checked (number)
for (int i = 0; i < checked.size(); i++) {
// Item position in adapter
position = checked.keyAt(i);
// Add location if it is checked i.e.) == TRUE!
if (checked.valueAt(i))
//add selected items to madapter
selectedItems.add(madapter.getItem(position));
}
//create string output array, store new string array with selected items
String[] outputStrArr = new String[selectedItems.size()];
for (int i = 0; i < selectedItems.size(); i++) {
outputStrArr[i] = selectedItems.get(i);
}
Intent intent = new Intent(getApplicationContext(),
MidwifeResultList.class);
// Create a bundle object
Bundle b = new Bundle();
b.putStringArray("selectedItems", outputStrArr);
// Add the bundle to the intent.
intent.putExtras(b);
// start the ResultActivity
startActivity(intent);
}
I have a result activity that is designed to collect the selected item and display it:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_midwife_result_list);
Bundle b = getIntent().getExtras();
String[] resultArr = b.getStringArray("SelectedItems");
ListView lv = (ListView) findViewById(R.id.list);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, resultArr);
lv.setAdapter(adapter);
}
When I run the program, I can see the listItem results, but when I select one the program stops, and there is this error:
Unable to start activity ComponentInfo{android.bignerdranch.com.mobilemidwife/android.bignerdranch.com.mobilemidwife.MidwifeResultList}: java.lang.NullPointerException: storage == null
pointing to this line of code:
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, resultArr);
The code seems to be right...why would there be a null value on resultArr?
b.putStringArray("selectedItems", outputStrArr);
...
String[] resultArr = b.getStringArray("SelectedItems");
You have a typo, in one place you write "selectedItems" and in another you write "SelectedItems". Notice the first letter is capitalized in one but not the other. You should change them to be the same.
Related
I need some help guys.
The problem is that I have a spinner that has commodities in it, such as chemicals,biscuits etc. but these commodities are stored in the database. I have written a web service that retrieves the commodities and the corresponding commodity code from database the web service works fine. I am getting the data in my android code. So I have stored the commodity in one array list say ar1, and the commodity code in one more array list say ar2. Now I want these commodity, what I have stored in ar1 to be displayed as spinner items and when user selects one of the spinner items, I must be able to retrieve the corresponding commodity code of that commodity.
Can some body help me??
I am using the below code but i am not able to get the desired result
String[] arr_Commodities = new String[ar2.size()];
spinnerMap = new HashMap<String, String>();
for (int i = 0; i < ar2.size(); i++)
{
spinnerMap.put(ar2.get(i),ar1.get(i));
arr_Commodities[i] = ar2.get(i);
System.out.println(arr_Commodities[i]);
}
ArrayAdapter<String> adapter =new ArrayAdapter<String>(getApplicationContext(),android.R.layout.simple_spinner_item, arr_Commodities);
adapter =new ArrayAdapter<String>(getApplicationContext(),android.R.layout.simple_spinner_item, arr_Commodities);
spin_commodity.setAdapter(adapter);
I find nothing is wrong with this code but i am still not able to pop[ulate the spinner some one please modify the above code..thank you
you can try this and improvise the loop on populating items:
final ArrayList<String[]> items = new ArrayList<String[]>();
for(int i= 0; i <10 ; i++){//sample loop populating items
String[] item = new String[2];
item[0] = "id";
item[1] = "commodities";
items.add(item);
}
Spinner s = new Spinner(context);//sample spinner
ArrayAdapter<String[]> adapter = new ArrayAdapter<String[]>(context , android.R.layout.simple_list_item_1, items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
s.setAdapter(adapter);
s.setOnItemSelectedListener(new OnItemSelectedListener(){
#Override
public void onItemSelected(AdapterView<?> parent,
View view, int position, long id) {
// TODO Auto-generated method stub
String[] selected = items.get(position);
//commodity id
String comId = selected[0];
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
// TODO Auto-generated method stub
}
});
String[] ar1={"chemicals","biscuits"};
String[] ar2={"1","2"};
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, ar1); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
your_spinner.setAdapter(adapter);
//to get the selected item position
int x=your_spinner.getSelectedItemPosition();
Your required code is
String code=ar2[x];
In my app, I want the users to see a list of cities, select the city, then see people associate with that city.
So, I have this to get the data:
protected void onResume() {
super.onResume();
setProgressBarIndeterminateVisibility(true);
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.orderByAscending(ParseConstants.KEY_LOCATION);
query.setLimit(1000);
query.findInBackground(new FindCallback<ParseUser>() {
#Override
public void done(List<ParseUser> users, ParseException e) {
setProgressBarIndeterminateVisibility(false);
if (e == null) {
// Success
mMidwifeLocation = users;
String[] locations = new String[mMidwifeLocation.size()];
String check;
int i = 0;
for(ParseUser user : mMidwifeLocation) {
check=user.getString("city");
if(check!=null){
if(!Arrays.asList(locations).contains(check)){
locations[i] = user.getString("city");
}
}
i++;
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
SearchingMidwife.this,
android.R.layout.simple_list_item_checked,
locations);
setListAdapter(adapter);
}
else {
Log.e(TAG, e.getMessage());
AlertDialog.Builder builder = new AlertDialog.Builder(SearchingMidwife.this);
builder.setMessage(e.getMessage())
.setTitle(R.string.error_title)
.setPositiveButton(android.R.string.ok, null);
AlertDialog dialog = builder.create();
dialog.show();
}
}
});
And this to pass the selected item to the new activity:
#Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id);
SparseBooleanArray checked = l.getCheckedItemPositions();
ArrayList<String> selectedItems = new ArrayList<String>();
for (int i = 0; i < checked.size(); i++) {
// Item position in adapter
position = checked.keyAt(i);
// Add sport if it is checked i.e.) == TRUE!
if (checked.valueAt(i))
selectedItems.add(adapter.getItem(position));
}
String[] outputStrArr = new String[selectedItems.size()];
for (int i = 0; i < selectedItems.size(); i++) {
outputStrArr[i] = selectedItems.get(i);
}
Intent intent = new Intent(getApplicationContext(),
MidwifeResultList.class);
// Create a bundle object
Bundle b = new Bundle();
b.putStringArray("selectedItems", outputStrArr);
// Add the bundle to the intent.
intent.putExtras(b);
// start the ResultActivity
startActivity(intent);
}
When I try it though, the app stops with an error once I select the item...
FATAL EXCEPTION: main Process: android.bignerdranch.com.mobilemidwife,
PID: 31604 java.lang.NullPointerException at
android.bignerdranch.com.mobilemidwife.SearchingMidwife.onListItemClick(SearchingMidwife.java:169)
Which points to this:
if (checked.valueAt(i)) selectedItems.add(adapter.getItem(position)); }
I declare adapter before onCreate:
ArrayAdapter adapter;
I assume this is the same adapter that is used in OnResume...something is not quite right, not sure what that would be. It seems like the adapter from onResume is not being passed into onResume, as it is null.
I am a bit new to this, so trying to learn this as best I can; I apologize if the problem is something missed that is simple.
Thanks so much for your help/insights
Michael Cabus
Your problem is here:
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
SearchingMidwife.this,
android.R.layout.simple_list_item_checked,
locations);
This is creating a local variable which is only scoped inside the method.
Change it to
adapter = new ArrayAdapter<String>(
SearchingMidwife.this,
android.R.layout.simple_list_item_checked,
locations);
by removing the leading ArrayAdapter<String> and that should fix this particular problem.
Update:
May I suggest using a different coding style such as putting leading underscore to your class member variables so that it's easier to detect these problems in the future? it's only a suggestion but I've found it immensely helpful to adapt this particular style.
What I mean is to for instance declare your variable like
ArrayAdapter _adapter;
in your class and then set it like this:
_adapter = new ArrayAdapter<String>(
SearchingMidwife.this,
android.R.layout.simple_list_item_checked,
locations);
Now every time you see "_", it's indicating that it's a member variable and not a local variable (since you would declare those without the leading underscore).
Just a personal suggestion. Up to you to adopt it or leave it.
I am trying to send row item from list view to another activity but maybe I do something wrong.
I made one app for food.
And I want when the user click to "First Activity" the list item from this listview to be send to "Second Activity" and when the user click to "Add to cart" the listview item go to Cart.class
But when I click to "Add to cart" the Activity is send me tо Cart.class but there have nothing.
In cart.xml I have listvew.
Sorry for my bad english
Thanks in advance.
First Activity.
public class UnderCal extends Activity {
String classes[] = {"Grilled chicken","Asiago","Spicy"};
int[] meal = new int[]{
R.drawable.grilledchicken,
R.drawable.asiago,
R.drawable.spicy
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.under_menu);
final List<HashMap<String,String>> aList = new ArrayList<HashMap<String,String>>();
for(int i=0;i<3;i++){
HashMap<String, String> hm = new HashMap<String,String>();
hm.put("food", Integer.toString(meal[i]));
hm.put("txt", "" + classes[i]);
aList.add(hm);
}
// Keys used in Hashmap
String[] from = {"food","arrow","txt"};
// Ids of views in listview_layout
int[] to = { R.id.food,R.id.arrow,R.id.txt};
// Instantiating an adapter to store each items
// R.layout.listview_layout defines the layout of each item
SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), aList, R.layout.list_layout, from, to);
// Getting a reference to listview of main.xml layout file
final ListView listView = ( ListView ) findViewById(R.id.mylist);
// Setting the adapter to the listView
listView.setAdapter(adapter);
listView.setDivider(new ColorDrawable(0xffffffff));
listView.setDividerHeight(1);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View v, int position, long id)
{
if (position == 0)
{
Intent intent = new Intent(UnderCal.this,GrilledChicken.class);
// intent.putExtra("get", aList.get(position));
String result = (String) listView.getItemAtPosition(position).toString();
intent.putExtra("get",result);
startActivity(intent);
overridePendingTransition(R.anim.animation3, R.anim.animation4);
}
}
});
}
Second Activity.
public class GrilledChicken extends Activity {
Button butadd;
//HashMap<String, String> hm;
String list;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.grilled_chicken);
//hash
// hm =(HashMap<String, String>)getIntent().getSerializableExtra("get");
Bundle extras = getIntent().getExtras();
list = extras.getString("get");
butadd=(Button) findViewById(R.id.butadd);
butadd.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(GrilledChicken.this,Cart.class);
// intent.putExtra("hm",hm);
intent.putExtra("list",list);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(intent);
}
});
Cart.class
public class Cart extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Remove title bar
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.cart);
Bundle extras = getIntent().getExtras();
String pos = extras.getInt("list");
}
}
For get item from your listview you have to write following code.
String item = food.get(position).toString();
Write this on your Itemclick method
Put the following code in your Cart.class
Bundle extras = getIntent().getExtras();
String list_data = extras.getString("list");
Now list_data contains the data.
There is another way through which you can do the task also.
Create a separate Global Class
Global.class
public class Globalclass {
public static String list_data;
}
And then in your FirstActivity replace the following
intent.putExtra("get",result);
with
Globalclass.list_data=result;
Now you can access the list_dataanywhere like the following
String data=Globalclass.list_data;
Try this once I hope this will help you.
First of all do this in YourFirstActivity
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(getActivity(), YourSecondActivity.class);
YourModel yourModel = (YourModel) parent.getItemAtPosition(position);
intent.putExtra("yourModel", yourModel);
startActivity(intent);
}
});
At another Activity do this.
YourModel yourModel= (YourModel) getIntent().getSerializableExtra("yourModel");
From yourModel object you will get all the data of your ListView selected item of YourFirstActivity to YourSecondActivity.
Multiple Send ListView Item:-
ArrayList<String>checked11 = new ArrayList<String>();
SparseBooleanArray checked = listView1.getCheckedItemPositions();
final ArrayList<String> selectedItems = new ArrayList<String>();
for (int i = 0; i < checked.size(); i++) {
int position = checked.keyAt(i);
if (checked.get(i))
selectedItems.add(checked11.get(position));
}
String[] outputStrArr = new String[selectedItems.size()];
for (int i = 0; i < selectedItems.size(); i++) {
outputStrArr[i] = selectedItems.get(i);
}
use Bunddle :
Bundle bundle = new Bundle();
Intent intent = new Intent(getApplicationContext(),
OtherActivity.class);
bundle.putStringArray("selectedItems", outputStrArr);
intent.putExtra("screen2", "sub");
intent.putExtras(bundle);
intent.putExtra(EXTRA_RESPONSE, selected);
startActivity(intent);
I have a list view that displays records from a database. Each row in the listview has a checkbox. How do I...
Create a toast message displaying the value of the selected item?
Identify the records selected by the user in the listview?
Iterate through each selected item and delete only the rows selected in the listview from the database?
I've been following this helpful tutorial here: //http://www.vogella.com/articles/AndroidSQLite/article.html
public class PhoneNumberDataBaseListView extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
NumbersDataSource datasource = new NumbersDataSource(this);
datasource.open();
String number = "123";
datasource.createNumber(number);
List<Number> values = datasource.getAllNumbers();
ArrayAdapter<Number> adapter = new ArrayAdapter<Number>(this, android.R.layout.simple_list_item_multiple_choice, values);
setListAdapter(adapter);
}
public void deleteNumber() {
NumbersDataSource datasource = new NumbersDataSource(this);
datasource.open();
ListView LV = (ListView) findViewById(android.R.id.list);
List<Number> values = datasource.getAllNumbers();
ArrayAdapter<Number> adapter = new ArrayAdapter<Number>(this, android.R.layout.simple_list_item_multiple_choice, values);
setListAdapter(adapter);
SparseBooleanArray checkedItems = LV.getCheckedItemPositions();
for (int i = 0; i < checkedItems.size(); i++) {
if(checkedItems.valueAt(i)) {
Number item = adapter.getItem(i);
Toast t = Toast.makeText(this, item.getNumber().toString(), Toast.LENGTH_LONG);
t.show();
}
}
}
Method getCheckedItemPositions() returns SparseBooleanArray that indicates which items are checked (if item on specific position is checked, method valueAt(position) invoked on that array returns true). Class DBAdapter from tutorial you are following provides you with deleteTitle(long rowId) method which you should use to acheive what you want.Therefore your code should look more or less like this:
SparseBooleanArray checkedItems = listView.getCheckedItemPositions();
for (int i = 0; i < checkedItems.size(); i++) {
if(checkedItems.valueAt(i)) {
db.deleteTitle(adapter.getItemId(i));
}
}
Of course SimpleCursorAdapter and DBAdapter should be stored in object attributes so that you have access to them from both methods (onCreate and deleteRecord). By the way, View parameter passed to deleteRecord method is not needed.
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);
}
}