I am developing an app which uses two fragments. One of the fragments uses a ListView to display items and when clicked, the second fragment updates itself (it is a dictionary app).
Once an item is selected in the ListView, I want it to be highlighted. I achieved this by using the following properties in XML file for ListView item.
android:choiceMode="singleChoice"
android:listSelector="#android:color/darker_gray"
This works fine as far as selection of the item is concerned. But the problem is when I scroll the list, the selection sometimes stays on the at the bottom or top of the list (as the case may be) even though the selected item is not present in the list. Here are screenshots to explain my problem.
The first pic shows no selection; in second pic, I selected 101 and hence second fragment was updated. In the third pic, even though 101 is not shown, a part of the ListView is highlighted.
What's the issue ?
Thanks.
EDIT
Here is the OnItemClick() method.
public void onItemClick(AdapterView<?> arg0, View view, int arg2, long arg3) {
String selectedWord = words.get(arg2); //words in an ArrayList which holds all the words displayed in this fragment.
Meaning meaningFragment = (Meaning) getSupportFragmentManager().
findFragmentById(R.id.fragmentMeaning);
meaningFragment.searchMeaning(selectedWord); //this method updates the other fragment.
}
EDIT:
This problem is not resolved yet. I have uploaded the project on github if anyone wants to have a look.
In Eclipse you can create a Master-Detail Flow which is an example of what you are trying to do.
For this create a "New Android Application" and in the third or forth screen which is called "Create Activity", three possibilities are offered to you, select the one called "Master/Detail".
This does not provide an answer to your question but is just pointing you to a working example where you can elaborate from.
Now for the answer to your question, I looked at your code and found the mistake.
Here is the working code for the onCreateView(). I commented out the wrong lines of code.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View v = inflater.inflate(R.layout.fragment_one, container);
listView = (ListView) v.findViewById(R.id.listView);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
//listView.setAdapter(new ArrayAdapter<String>(getActivity(),
// android.R.layout.simple_dropdown_item_1line, array));
//listView.setSelector(android.R.color.holo_blue_dark);
listView.setAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_activated_1, array));
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
listView.setItemChecked(position, true);
FragmentTwo frag = (FragmentTwo) getActivity()
.getFragmentManager()
.findFragmentById(R.id.fragmentTwo);
frag.updateTextView(array[position]);
}
});
return v;
}
In your code the 2 following lines are wrong
listView.setAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_dropdown_item_1line, array));
listView.setSelector(android.R.color.holo_blue_dark);
what you do here is set a simple_dropdown_item_1line which is not what you want and you manually set the selector.
You have to use simple_list_item_activated_1 and not set the selector manually.
listView.setAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_activated_1, array));
//listView.setSelector(android.R.color.holo_blue_dark);
If you want a custom selector color, you can create a custom selector by copying the simple_list_item_activated_1 and editing it to your needs and calling the edited layout.
However I recommend using the default colors so the day Android decides to change its color scheme you will be compliant to the new one.
In summary, to have the ListView.CHOICE_MODE_SINGLE working, you have to use simple_list_item_activated_1 and not manually set the selector.
Related
Up front: This is my first attempt at an Android app. I'm in that strange place of not knowing what to search for to find the answer to my question.
What I have accomplished is:
Created a custom class myCustomClass with properties of 'title' and 'youTubeUrl'
Created an ArrayList<myCustomClass>
Added multiple elements to ArrayList<myCustomClass>
Created a custom ArrayAdapter and attached it to the the arraylist.
Added an onItemClickListener to the custom ArrayAdapter.
All of that works good. I would like to show the title in the ListView and then when the user clicks the list view item, I'd like to get a reference to the youtubeUrl property.
Here's what I have for the adapter code:
MyListAdapter myListAdapter = new MyListAdapter(this, R.layout.my_list, elements);
myList.setAdapter(myListAdapter);
myList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String item = ((TextView)view).getText().toString();
Toast.makeText(getBaseContext(), item, Toast.LENGTH_LONG).show();
}
});
myListAdapter.notifyDataSetChanged();
Thanks for your help.
You can use the position property in onItemClick to go back to your data source and find the relevant item. From there you should be able to retrieve the Url.
As another poster implied, it depends on what you are using in your adapter. Assuming it's MyCustomClass. You can do something like this in your onItemClick method:
MyCustomClass selection = (MyCustomClass) getListView().getItemAtPosition(position);
While attempting to populate the items in a ListView following the outcome of a switch statement, I am encountering some sort of error. The application force closes inside the emulator, and when I ran it through the Eclipse debugger it shows the main thread has hung due to an IllegalStateException.
Aside from it meaning the obvious that it has entered some sort of wrong state, how do I fix it? I'm trying to do all of this from inside an OnItemClickListener, so that when the item is clicked, a switch statement evaluates which item was clicked, and then assigns an according ListAdapter to the ListView depending on the outcome of the switch. Is this the correct way to go about it? And if so, what in my code below is throwing the error?
final ListView lv = (ListView) findViewById(R.id.main_list);
final String[] autos = getResources().getStringArray(R.array.auto_array);
final ListAdapter la_auto = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_2, autos);
And then further down in the portion dealing with the onclicklistener
gallery.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView parent, View v, int position, long id)
{
switch(gallery.getSelectedItemPosition())
{
case 0:
lv.setAdapter(la_auto);
break;
EDIT: The LogCat stack trace is stopping at this error, "You must supply a Resource ID for a TextView, and the stack is hung at this point: ArrayAdapter.createViewFromResource(int, View, ViewGroup, int) line: 347
Any suggestions? I imagine it has something to do with the parameters I'm passing to the onItemClicked method.
Try android.R.layout.simple_list_item_1.
The answer is in simple_list_item_2.xml:
<TwoLineListItem xmlns:android="http://schemas.android.com/apk/res/android"
...
You need to use a resource that contains only a TextView. simple_list_item_1.xml fits the bill:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
...
Try browsing other possibilities here or making your own if you don't see any you like.
It would probably be better to start a new Activity with a new ListView and adapter.
You can pass the selected item as a parameter in your Intent:
Intent = new Intent(MyActivity.this, ActivityToStart.class);
intent.putExtra("selected", position);
startActivity(intent);
and retrieve it later in your other activity's onCreate method with:
int position = getIntent().getIntExtra("selected");
You may want to think about what information you would like to share between the activities. Using multiple activities will allow your user to press the back button and return to the original list as well.
Ok, so I have this application that takes a adress strings (from values/xml) and parses it your current position) retuning a name, address and distance away. This is then picked up by an arrayadapter and put up on a listview. I cannot for the life of me get the list view to accept an onitemclick to start another activity, where I can launch a different view. I did have it where I was getting the row, name and address to show through to an alert dialog, but in my efforts to get it to launch an activity, I lost that.
So does anyone have any thoughts? I am using the following call to make my list and and arrays. This is stripped down, so assume I have all the imports and proper formatting. I know I am just missing something simple here...
public class Wf extends ListActivity {
private ArrayList<String> DistanceList;
private ArrayAdapter<String> aa;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Bind the ListView to an ArrayList of strings.
DistanceList = new ArrayList<String>();
ListView lv = (ListView)findViewById(R.id.ListView01);
aa = new ArrayAdapter<String>(getApplicationContext(),
R.layout.listbox_layout,
DistanceList);
lv.setAdapter(aa);
//Call to get distance... here
}
public void onListItemClick(ListView parent, View v,int position, long id) {
ListView lv = (ListView)findViewById(R.id.ListView01);
Toast.makeText(this, "You clicked", Toast.LENGTH_LONG).show();
}
From the ListActivity docs:
ListActivity has a default layout that
consists of a single, full-screen list
in the center of the screen. However,
if you desire, you can customize the
screen layout by setting your own view
layout with setContentView() in
onCreate(). To do this, your own view
MUST contain a ListView object with
the id "#android:id/list" (or list if
it's in code)
Your ListView does not have the correct ID. Your code is incomplete but I suspect the listener is not being registered with the ListView.
Alright, so I followed a tutorial on the Android website, and I got a ListView going in my application. But, the example they had did everything in Java basically. How could I transform the following code to XML?
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, COUNTRIES));
ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// When clicked, show a toast with the TextView text
Toast.makeText(getApplicationContext(), ((TextView) view).getText(), Toast.LENGTH_SHORT).show();
}
});
I know I can't make the click listener XML, I just put that there for example.
You don't really need to change anything to XML in that particular piece of code. ListActivity will use a full-screen ListView if there is no call to setContentView(). Here is an example of a ListActivity with a custom layout, if that is what you are interested in.
Also, please get rid of getApplicationContext(). Just use this to reference the Activity, which itself is a Context.
I am new to android development, and not very good at programming in general but, I am working on a tab layout that has a listview per tab. Each tab has it's own java file. I am currently trying to add a context menu that when clicked (not long clicked) on an item in my listview, will bring up a menu so I can choose an option. Right now it just shows a toast displaying the name of the item I clicked. The listview options are currently added to the list via local string declaration, here is an example of on of my tabs:
public class AlbumTab extends ListActivity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
final String[] CDExplorer_tabs = new String[] {"Client Heirarchy", "Territory", "Sales Credit", "Admin", "General Search"};
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, CDExplorer_tabs));
ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
{
Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
Toast.LENGTH_SHORT).show();
}
});
}
would I have to make another string array for each menu I want to popup and somehow connect it to the other string? Or do if statements that decide on which menu to popup based on which listview item is clicked?
First, you if you want each part of the list to have a different menu, make a switch statement in your onItemClick() that depends on your position. switch(position){ //cases and such
Then what you might want to try instead of having a nested ListView is try doing an AlertDialog. Search for adding a list. And then implementing that for each position on your list. Then make sure that you implement another switch inside of the DialogInterface onClick function to call a function to do what you what it to do from the list.//Also make sure to alert.show();.
That would be my recommendation if you want to do it. However, if you want to do nested listviews, its more complicated but possible.
What you need to is implement a custom list adapter for you list. And create a view holder for each that holds a another listview. A good example for that is here.
That should pretty much do it. Mind you that if you decide to do the nested listviews it will be very crowded inside that listview.