I currently have a custom listview where each item on the list contains two rows of text. What I would like to do is each time a user clicks on the button, it creates a new item on the list with the text that the user inputted. While I know how to get the text, I am having trouble adding a new item to the list view as I simply don't know where to begin.
Here is my code:
public class MainFeedActivity extends ListActivity implements OnClickListener {
View sendButton;
EditText postTextField;
TextView currentTimeTextView, mainPostTextView;
ListView feedListView;
String[] test;
ArrayList<HashMap<String, String>> list;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_feed);
//create button and implement on click listener
sendButton = this.findViewById(R.id.sendPostButton);
sendButton.setOnClickListener(this);
list = new ArrayList<HashMap<String, String>>();
//create the adapter for the list view
SimpleAdapter adapter = new SimpleAdapter(
this,
list,
R.layout.post_layout,
new String[]{"time", "post"},
new int[]{R.id.postTimeTextView, R.id.postTextView});
//fill the list view with something - TEST
fillData();
//set list adapter
setListAdapter(adapter);
}
public void fillData() {
//long timeTest = System.currentTimeMillis();
HashMap<String, String> temp = new HashMap<String, String>();
temp.put("time", "current time");
temp.put("post", "USER TEXT GOES HERE");
list.add(temp);
}
#Override
public void onClick(View button) {
switch (button.getId()) {
case R.id.sendPostButton:
break;
}
}
}
It's as simple as adding a new element to your ArrayList (like you do in fillData), then calling adapter.notifyDataSetChanged().
After calling fillData(), just make a call on adapter.notifyDataSetChanged().
NotifyDataSetChanged() - Notifies the attached View that the underlying data has been changed and it should refresh itself.
Related
My app implements a HashMap, such that when a key is typed in the AutoCompleteTextView editText, and user clicks a dropdown item, the value gets displayed on a textView.
The only problem is that the clicked drop-down item does not respond on the first click (this only happens once, after the app is launched but works fine subsequently), the user MUST re-type a key and click the item before it displays the value.
Any suggestions as to how to resolve this?
Java code:
public class MainActivity extends ActionBarActivity
{
Map<String, String> map = new HashMap<String, String>();
private EditText autocomplete_searchField;
private TextView displayField;
String note;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
autocomplete_searchField = (AutoCompleteTextView) findViewById(R.id.autocomplete_searchField);
// Gets a reference to the AutoCompleteTextView in the layout
final AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.autocomplete_searchField);
// Gets the string array
String[] musicNote = getResources().getStringArray(R.array.music_notes_array);
// Creates the adapter and set it to the AutoCompleteTextView
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, musicNote);
textView.setAdapter(adapter);
displayField = (TextView) findViewById(R.id.displayField);
textView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id){
displayField.setText(map.get(adapterView.getItemAtPosition(position).toString()));
String note = autocomplete_searchField.getText().toString();
displayField.setText(map.get(note));
map.put("Doe", "a deer, a female deer");
map.put("Ray", "a drop of golden sun");
}
Most of the related solutions I've seen treat buttons, but not AutoCompleteTextView drop-down items. I've also tried setting focus both in my JAVA and XML but those didn't resolve the issue.
I didn't understand very well what you are trying to do, but looking in your code, I saw a couple of wrong things in it. Perhaps it is the problem. Moreover I added some lines into your code, so the here is it:
public class MainActivity extends ActionBarActivity {
private Map<String, String> map = new HashMap<String, String>();
private AutoCompleteTextView autocomplete_searchField;
private TextView displayField;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
autocomplete_searchField = (AutoCompleteTextView) findViewById(R.id.autocomplete_searchField);
displayField = (TextView) findViewById(R.id.displayField);
// Gets the string array
String[] musicNote = getResources().getStringArray(R.array.music_notes_array);
// Creates the adapter and set it to the AutoCompleteTextView
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, musicNote);
autocomplete_searchField.setAdapter(adapter);
autocomplete_searchField.setThreshold(1);
autocomplete_searchField.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
autocomplete_searchField.showDropDown();
}
});
autocomplete_searchField.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id){
displayField.setText(map.get(adapterView.getItemAtPosition(position).toString()));
}
}
}
}
Test it before do any change in order to realize if the issue was fixed. Then you do whatever you wanna do ;)
I am a beginner and trying to do my first android app.
I have the following requirement.
When the user clicks on the item in the list, we should be able to navigate to a new page based on the item clicked.
Right now I have a sample code wherin I am able to navigate to only one page irrespective of the item clicked.
For exmple, When I click on football in list I should be able to navigate to a new page called by football class and when I click on basketball I should be able to navigate to a new page called by basketball class.
Also I want to add an actionbar to this listview.
I am able to create an actionbar with home, logout and settings option separately . But I am not able to add it to this list view.
Please suggest regarding how to go about this
Below is my code:
public class ImageTextListViewActivity extends Activity implements
OnItemClickListener {
public static final String[] titles = new String[] { "Football",
"Basketball" };
public static final Integer[] images = { R.drawable.football,
R.drawable.basketball };
ListView listView;
List<RowItem> rowItems;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
rowItems = new ArrayList<RowItem>();
for (int i = 0; i < titles.length; i++) {
RowItem item = new RowItem(images[i], titles[i]);
rowItems.add(item);
}
listView = (ListView) findViewById(R.id.list);
CustomListViewAdapter adapter = new CustomListViewAdapter(this,
R.layout.list_item, rowItems);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
//Navigation to next page
Intent myIntent = new Intent(view.getContext(), Football.class);
myIntent.putExtra("Game",listView.getItemAtPosition(position).toString());
startActivityForResult(myIntent, 0);
//Navigation ends
}
}
Why don't you use the position param of onItemClick method?
I am developing android apps. In my apps having two activities, first activity is displaying list and in second activity having spinner and listview in the same activity and when user click on the item from spinner the listview will be displayed. when user navigate from first activity to second activity then spinner is properly populated with listview. but problem is that after listview displayed properly then spinner item was blank. I don't know where i am doing wrong. Please anybody have solution.
Here i am posting few code of Second Activity
public class ProjectDetailActivity extends SherlockListActivity {
private List<String> list = new ArrayList<String>();
private ArrayList<HashMap<String, String>> list2 = new ArrayList<HashMap<String,String>>();
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_project_detail);
//get spinner item from server when user comes from first activity.
new LoadPhaseData().execute();
//Listener for Phase spinner
projSpinnerPhase.setOnItemSelectedListener((OnItemSelectedListener) new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
//get listview when user click item from spinner
new LoadPhaseData().execute();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
//this adapter for listview when click item from spinner
ListAdapter phaseAdapter = new SimpleAdapter(getApplicationContext(),
list2, R.layout.phase_avail_list_item,
new String[] {PHASE_NAME}, new int[]
{R.id.phaseName});
setListAdapter(phaseAdapter);
}
private class LoadPhaseData extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... params) {
//Here I am calling web service for spinner and listview
}
#Override
protected void onPostExecute(Void result) {
//following adapter for spinner item
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(
getApplicationContext(),android.R.layout.simple_spinner_item,list);
dataAdapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
projSpinnerPhase.setAdapter(dataAdapter);
}
}
}
Thanks in advance
This is because you are assigning new Adapter to the Spinner with new values while you are adding new rows to Spinner. Spinner losses its previous row along with the previous data and get another Adapter with new data rows. You need to append these value to the existing data-holder (may be an array or ArrayList) and then call the adapter.notifyDataSetChanged();
You need to move ArrayList to the class-level, (i.e make it class field) then while you have downloaded data. just append new data to the list and call adapter.notifyDataSetChanged();
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);
}
}
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...