I am creating a Spinner instance that I bind to my own custom adapter class (derived from BaseAdapter). In it, I create a bunch of custom "cell" LinearLayout-derived instances that I inflate from xml to be used for each item in the spinner.
Everything looks fine as expected, but whenever the items in "drop down" mode are clicked, the drop down dialog does not get dismissed.
I can trap the click notification inside my cell class, but what is the magic sauce I need to tell the spinner that an item was selected and that it should dismiss the drop down?
My cell class is inflated from the following xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/VIEW_LEAF"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView android:id="#+id/STATIC_LEAF_NAME"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:paddingLeft="3dip"
android:paddingTop="20dip"
android:paddingBottom="20dip"
android:textSize="22sp"
android:textStyle="bold"
android:text=""
android:layout_gravity="left|center_vertical"
android:textColor="#color/black_enabled_grey_disabled"
/>
</LinearLayout>
My cell class looks like so:
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.view.View.OnClickListener;
// This class is responsible for rendering the data in the model.
public class DataCell extends LinearLayout implements OnClickListener
{
private final String TAG = getClass().getSimpleName();
public DataCell(Context context)
{
super(context);
m_context = context;
final boolean attachToRoot = true;
LayoutInflater.from(context).inflate(R.layout.data_cell,
this, attachToRoot);
m_labelName = (TextView) findViewById(R.id.STATIC_LEAF_NAME);
m_labelName.setOnClickListener(this);
}
// Update the views with the data corresponding to selection index.
// If dropDown is true, this view is to be displayed in a dropped down
// list.
public void display(int index, ViewGroup parent, Data data, boolean dropDown)
{
m_data = data;
m_labelName.setText(data.getFriendlyName());
setFocusable(true);
}
#Override
public void onClick(View view)
{
ViewParent parent = getParent();
if(parent instanceof Spinner)
{
//((Spinner)parent).setSelection(2);// TODO something here?
}
}
private TextView m_labelName = null;
#SuppressWarnings("unused")
private Context m_context = null;
#SuppressWarnings("unused")
private Data m_data = null;
}
Thanks!
swine
So you were right about the cell stealing the clicks. But there was a very simple solution to all this, just not very obvious. All I had to do is make the TextView inside my DataCell not respond to clicks.
So I removed the m_labelName.onClickListener() call completely, and instead, at that location, put in the following code:
m_labelName.setClickable(false);
m_labelName.setFocusable(false);
m_labelName.setFocusableInTouchMode(false);
I would delete the entire DataCell class, since it is doing you no good. If I had to guess, 99.9% of the uses of Spinner do not involve creating your own subclass of LinearLayout.
If there is more to this class than you elected to show, enough to make it worthwhile, then you should not be intercepting and consuming the click events. Spinner handles that automatically. If I had to guess, 99.999% of the uses of Spinner do not involve the contents of the dropdown list being involved in click events.
Related
The title of this post says it all.
This code works without any problems:
package abc.AvailableCars;
import android.graphics.Color;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class carListActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.car_list_layout);
final ListView carListview = (ListView) findViewById(R.id.list_view);
final Button dButton = (Button) findViewById(R.id.disable_button);
String[] cars = {"Maxima GXE", "Passat", "Focus SE", "Mazda6", "Avalon", :Sentra GXE"};
final List<String> list_of_cars = new ArrayList<String>(Arrays.asList(cars));
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>
(this, android.R.layout.simple_list_item_1, list_of_cars);
carListview.setAdapter(arrayAdapter);
dButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int chosenRow = 3;
carListview.getChildAt(3).setEnabled(false);
carListview.getChildAt(3).setBackgroundColor(Color.parseColor("#3f51b5"));
}
});
}
}
This is in my listview .xml file:
<Button
android:id="#+id/disable_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Disable A Row"
/>
But, when I comment-out everything that belongs to the button, like below, and the Car List class is called, the app crashes with the error in the Logcat:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setEnabled(boolean)' on a null object reference:
final ListView carListview = (ListView) findViewById(R.id.list_view);
//final Button dButton = (Button) findViewById(R.id.disable_button);
String[] cars = {"Maxima GXE", "Passat", "Focus SE", "Mazda6", "Avalon"};
final List<String> list_of_cars = new ArrayList<String>(Arrays.asList(cars));
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>
(this, android.R.layout.simple_list_item_1, list_of_cars);
carListview.setAdapter(arrayAdapter);
//dButton.setOnClickListener(new View.OnClickListener() {
//#Override
//public void onClick(View v) {
int chosenRow = 3;
carListview.getChildAt(chosenRow).setEnabled(false);
carListview.getChildAt(chosenRow).setBackgroundColor(Color.parseColor("#3f51b5"));
}
//});
}
//}
I'm not an Android newbie anymore, but this is eluding me.
I want the chosen row to be disabled and the color set as soon as the listview is shown.
How can I do this programmatically without a button?
I have tried every variation I can think of, getView(), even a fake click.
Just in case it makes a difference, this code is in a separate class and file than the MainActivity.java file, and is called in that file.
There has to be a simple answer. What do I need to change?
Please be verbose.
Thank you.
You are calling carListview.getChildAt(chosenRow) when you set up your list view, in onCreate. Your list view is not ready yet. Try moving this code to your onResume - should look something like this:
#Override
public void onResume(){
super.onResume();
arrayAdapter.notifyDataSetChanged();
int chosenRow = 3;
carListview.getChildAt(chosenRow).setEnabled(false);
carListview.getChildAt(chosenRow).setBackgroundColor(Color.parseColor("#3f51b5"));
}
This is a pretty simple case - your chosenRow number is generated by you. You might need a custom Adapter if you need it to be algorithmic or user-driven. Have a look at this tutorial.
From my understanding, since listViews are views, they have to be Overridden for some things to be changed in them.
I chose not to disable the required rows, but check for them in code.
The complete code that works is below.
Some credit goes to Raghunandan for his/her answer at-
Android - Change background color of specific item of ListView
Again, sorry, but the indentation of the code wouldn't work correctly for some reason.
import android.graphics.Color;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CarListActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.car_list_layout);
final ListView carListview = (ListView) findViewById(R.id.list_view);
String[] cars = {"European Cars:", "Mercedes", "Passat", "Bently", "Porsche", "BMW", "Yugo","Land Rover",
"Japanese Cars:", "Maxima GXE", "Mazda6", "Avalon", "Toyota", "Honda", ""};
final List<String> list_of_cars = new ArrayList<String>(Arrays.asList(cars));
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>
(this, android.R.layout.simple_list_item_1, list_of_cars);
//------------------------------------------
carListview.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list_of_cars) {
// Since listViews are views, they have to be Overrdden for some things to be changed in them.
#Override
public View getView(int rowPosition, View convertView, ViewGroup parent) {
View row = super.getView(rowPosition, convertView, parent);
//------------------------------------------
// This works. I have only tried this for two rows, the two I wanted. I expected this line to crash the app, but it didn't.
if(getItem(rowPosition).equals("European Cars:") || getItem(rowPosition).equals("Japanese Cars:")) {
// Make the two rows have a white background color.
row.setBackgroundColor(Color.WHITE); // this command WORKS fine by itself.
// row.setEnabled(false); this command caused "bleeding" over into other rows, so I will check for the rows in a condition.
} // both of the getItems end here.
else {
// All of the other rows should have this color.
row.setBackgroundColor(Color.parseColor("#EEE8AA"));
// the default color
} // else ends here.
//------------------------------------------
return row;
//------------------------------------------
} // getView ends here.
}); // carListview.setAdapter ends here.
} // onCreate ends here.
} // CarListActivity ends here.
Thanks, and I hope this helps others.
It's my first time trying to make an App that is basically a checklist that helps me keep track of i.e. collected items. Much like a checklist in a game. I am veeeeery inexperienced with Android so I found some template that I modified for my own need. I'm basically using two .png files (checked and unchecked box) as ImageView which upon clicking change into one another, thus imitating a basic checkbox. Aparently this method worked best for me, even though I thought a normal checkbox object would be easier. When i used regular checkbox objects the status of 'checked' moved throughout the list... And with this ImageView method the checked boxes remained the same as the ones I really checked.
So I figured how to generate a List. Later on I will manually change the list to the Items/Names/etc. as I want that won't be a problem. The App also manages to let me select multiple Items and the items remain checked even after its onPause.
The problem I face now is that upon distroying the app on the device and on restarting the app, all the checked Items are now unchecked. That means that the information that the item was check was not stored at all.
I would be so happy if someone can help me with completing the code... I have no idea how to store the information of which Item in List was checked and let alone be reloaded upon onCreate.
Here is activity_main.xml, which is basically the ListView.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="15dp"
android:paddingTop="15dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
tools:context="com.multiselect.MainActivity">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listview"
android:divider="#android:color/darker_gray"
android:dividerHeight="2dp"/>
</RelativeLayout>
Next up is the list_view_item.xml where the Name, Subtitle and Checkbox ImageView are declared.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="60dp">
//NAME//
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tv_user_name"
android:gravity="center_vertical"
android:layout_toEndOf="#+id/iv_check_box"
android:paddingStart="10dp"
android:textAppearance="?android:attr/textAppearanceLarge" />
//SUB
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tv_user_sub"
android:layout_alignStart="#+id/tv_user_name"
android:layout_below="#+id/tv_user_name"
android:paddingStart="10dp"
android:textColor="#color/sub"
android:textAppearance="?android:attr/textAppearanceMedium"
tools:ignore="RtlSymmetry" />
//Checkbox
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:id="#+id/iv_check_box"
android:layout_alignParentStart="true"
android:onClick="onCheckboxClicked"
android:layout_centerVertical="true"
android:background="#drawable/check"/>
</RelativeLayout>
So then I have a basic UserModel.java with all the Getters and Setters.
package com.multiselect;
public class UserModel {
private boolean isSelected;
private String userName;
private String userSub;
//create constructor and getter setter
public UserModel(boolean isSelected, String userName, String userSub) {
this.isSelected = isSelected;
this.userName = userName;
this.userSub = userSub;
}
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserSub() {
return userSub;
}
public void setUserSub(String userSub) {
this.userSub = userSub;
}
}
Then I know I need an CustomAdapter.java for what I wanna do. I have a ViewHolder inside together with an updater for the checle items.
package com.multiselect;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
public class CustomAdapter extends BaseAdapter {
Activity activity;
List<UserModel> users;
LayoutInflater inflater;
//short to create constructer using alt+insert or rightclick - generate - constructor
public CustomAdapter(Activity activity) {
this.activity = activity;
}
public CustomAdapter(Activity activity, List<UserModel> users) {
this.activity = activity;
this.users = users;
inflater = activity.getLayoutInflater();
}
#Override
public int getCount() {
return users.size();
}
#Override
public Object getItem(int i) {
return i;
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder = null;
if(view == null){
view = inflater.inflate(R.layout.list_view_item, viewGroup, false);
holder = new ViewHolder();
holder.tvUserName = (TextView)view.findViewById(R.id.tv_user_name);
holder.tvUserSub = (TextView)view.findViewById(R.id.tv_user_sub);
holder.ivCheckBox = (ImageView) view.findViewById(R.id.iv_check_box);
view.setTag(holder);
}else
holder = (ViewHolder) view.getTag();
UserModel model = users.get(i);
holder.tvUserName.setText(model.getUserName());
holder.tvUserSub.setText(model.getUserSub());
if (model.isSelected()) {
holder.ivCheckBox.setBackgroundResource(R.drawable.checked);
}
else
holder.ivCheckBox.setBackgroundResource(R.drawable.check);
return view;
}
public void updateRecords(List<UserModel> users) {
this.users = users;
notifyDataSetChanged();
}
class ViewHolder{
TextView tvUserName;
TextView tvUserSub;
ImageView ivCheckBox;
}
}
...And MainActivity.java:
package com.multiselect;
import android.app.Activity;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.AdapterView;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;
import android.content.SharedPreferences;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.listview);
final List<UserModel> users = new ArrayList<>();
for(int i = 0; i<20; i++) {
users.add(new UserModel(false, "Name "+(i), "Subtitle " + (i)));
}
final CustomAdapter adapter = new CustomAdapter(this, users);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
UserModel model = users.get(i);
if (model.isSelected())
model.setSelected(false);
else
model.setSelected(true);
users.set(i, model);
//now update adapter
adapter.updateRecords(users);
}
});
}
}
And now I know I should use SharedPreferences in the MainActivity.java but I don't know how in this specific example...
Especially when I try it out with what other people said the app just crashes either as soon as I check something or when I just try to Run the app. I'm literally not good enough for this and I really want to know how something I normally take for granted (that an app remembers whats been don in it) is done programmatically.
I hope that someone can complete my Code so that the app remembers which box was checked and reloads that upon onCreate...
First, u need to add a unique attribute to your user model. like userId
private int userId
then add setters and getters like other attributes. I think then u can use tinyDB to stores recent value of this userId. Then u can increment this userId when new user model added.
TinyDB tinydb = new TinyDB(context);
int recentid = tinydb.getInt(recentUserId) == null ? 0:tinydb.getInt(recentUserId)
tinydb.putInt("recentUserId",recentid++);
userModel1.setUserId(recentid)
After that, You can create array list with checked ids. If the user checked any post then update that list. If user unchecked that list then remove id from list.
List<int> checkedList = new ArrayList<>;
checkedList.add(..userid);
Then u can update TinyDb when you update that checked list using below command.
tinydb.putList("checkedIdList", chekcedList);
when app starting state u need to call this tinydb and get checked list using below command
tinydb.getList("checkedIdList");
then u can update your list with checked and unchecked states
PS: u can nevigate to https://github.com/kcochibili/TinyDB--Android-Shared-Preferences-Turbo this and get idea about tinydb as well. It is kind of good improvement of shared preferences
You need to do following thing in onCrete method to avoid always update checkList.
List<int> checkedList = new ArrayList<>;
if(tinydb.getList("checkedIdList")!= null){
checkedList = tinydb.getList("checkedIdList")
}
I am creating my very first Android application, but i stuck unfortunately. The application would be very simple: On the starting page there is a ListView with items like:
1st group
2nd group
3rd group
...
By clicking on any of these items a new page would show up with a single textview element that would have some description. Like you click on '1st group' item, the listview gets hidden, and a new page appears with '1st group description' text.
So far I can show the listview with the items, but when I click on them, nothing happens (i guess I miss some basic stuff, but as a very newby, i cannot find it out easily).
import java.util.ArrayList;
import java.util.Arrays;
import android.app.Activity;
import android.os.Bundle;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ListView;
import android.widget.TextView;
import android.view.*;
public class SimpleListViewActivity extends Activity {
LinearLayout.LayoutParams layoutParams;
LinearLayout ll;
private ListView mainListView ;
private ArrayAdapter<String> listAdapter ;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Find the ListView resource.
mainListView = (ListView) findViewById( R.id.mainListView );
// populate the List of groups
String[] GROUP = getResources().getStringArray(R.array.group);
ArrayList<String> GrList = new ArrayList<String>();
GrList.addAll( Arrays.asList(GROUP) );
// Create ArrayAdapter using the list.
listAdapter = new ArrayAdapter<String>(this, R.layout.simplerow, GrList);
// Set the ArrayAdapter as the ListView's adapter.
mainListView.setAdapter( listAdapter );
ll = (LinearLayout)findViewById(R.id.LinearLayout);
layoutParams = new LinearLayout.LayoutParams
(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
mainListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView t = (TextView) findViewById(R.id.textView1);
String[] DESC = getResources().getStringArray(R.array.desc);
t.setText(DESC[position]);
ll.addView(t);
//This is the point that is wrong for sure (and others maybe also). I cannot get the textview shown
}
});
}
}
Thanks for your help.
Have you tried displaying a toast message or setting a breakpoint within your onItemClick() method to verify that its not being reached? My guess is that it is and you are running into one of the issues described here:
Refreshing a LinearLayout after adding a view
I am assuming your R.layout.main is holding a listview and a linear layout with ids R.id.mainListView, and R.id.LinearLayout respectively.
Example: I left out some of the obvious attributes you would need like height width etc..
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
>
<ListView android:id="#+id/mainListView" />
<LinearLayout android:id="#+id/LinearLayout" />
</RelativeLayout>
In your on item click, all you will do is add a textview as you have done, then set the mainListView.setVisibility(View.INVISIBLE) and ll.setVisibility(View.VISIBLE).
If your R.layout.main is not using a RelativeLayout as the root node, but is instead using a LinearLayout you should still be able to achieve the same effect by setting the Visibilities to View.GONE if you want it to hide, and View.VISIBLE if you want it to show.
To revert back to being able to see the list view I would override onBackPressed() in the activity, to invert the Visibilities on the two items. Also remember to remove all views from the linear layout so that the next time an item in the group is selected it will be the only item in the linear layout when it is added.
There are much easier ways to accomplish this, such as firing off a new activity for viewing the next item, but seems you are keeping everything within one activity. I would also think about using a ListActivity instead of base activity class.
Hope this helps.
First off stop using the word page. Call it an activity (gotta get you in the Android zone)
Once the click happens start a new activity like so:
mainListView.setOnItemClickListener(new OnItemClickListener() {
String textToPass = GrList.get(position)
Intent i = new Intent(getBaseContext(), SecondActivity.class);
i.putExtra("textToPass", textToPass);
startActivity(i);
}
You'll obviously need to have that second activity with its corresponding layout file defined. Also in the second activity look up how to get the bundle and extras from the first activity in order to get the textToPass String
Can someone please tell me how to create a custom adpater for this list, as i dont want toast to display when a user clicks the list item, but, When a user clicks on Google, he will be navigated to "www.google.com" and "www.yahoo.com" and same for msn.com,,
cant figure out at all, stuck for last 1 week, even though i know how to create a intent and call a URI but not working or right for this,
can someone just modify this please ?
import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class FurtherEducationCourses extends ListActivity
{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, FURTHER_EDUCATION));
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();
}
});
}
static final String[] FURTHER_EDUCATION = new String[] {
"GOOGLE", "YAHOO", "MSN"
};
}
xml file, dunno why u required :s
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp" >
</TextView>
The trick is to get the item at that position, then depends on the position (or even the value at the position), you call the correct link.
So you need to index the value like this, put this code after your static final... statement.
HashMap<String, String> valueToLink = new HashMap<String, String>;// key is Google, Yahoo, value is www.google.com
valueToLink.put("GOOGLE", "www.google.com");
//add yahoo,.etc.
In onItemClick() function, replace the toast by this:
String link = valueToLink.get(((TextView) view).getText());
//code to open the link here
I'm developing an simple application on Android, where some items are shown on a list. The user may click on one, taking him to a further activity. Basics...
But my OnItemClickListener does not get called! I've found this very similar question, but the solution (disallow the list item view to get focus) does not work for me. However, a long click gets catched - my OnItemLongClickListener gets called. Please have a look at the following code and try it yourself. This is a simplified version of my code, showing the buggy behavior. Btw: I'm using Andriod SDK 2.0 with Eclipse 3.5.1.
package de.sacherkhoudari.listtest;
import java.util.LinkedList;
import java.util.List;
import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
public class ListTest extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final List<ListEntry> lEntries = new LinkedList<ListEntry>();
for ( int ii = 0; ii < 10; ii++ )
lEntries.add( new ListEntry( "Entry " + ii ) );
setListAdapter( new ArrayAdapter<ListEntry>( this, R.layout.list_item, lEntries ) );
ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener( new OnItemClickListener() {
public void onItemClick( AdapterView<?> parent, View view, int position, long id ) {
Toast.makeText( ListTest.this, "ItemClick at item " + lEntries.get(position).toString(), Toast.LENGTH_LONG ).show();
}
});
lv.setOnItemLongClickListener( new OnItemLongClickListener() {
public boolean onItemLongClick( AdapterView<?> parent, View view, int position, long id ) {
Toast.makeText( ListTest.this, "ItemLongClick at item " + lEntries.get(position).toString(), Toast.LENGTH_LONG ).show();
return false;
}
});
setContentView(lv);
}
}
class ListEntry {
private String name;
public ListEntry( String s ) {
name = s;
}
public String toString() {
return name;
}
}
So far the Java code... here comes the layout list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp"
android:focusable="false" >
</TextView>
Note: android:focusable="false" has no effect.
Thanks!
Sacher
When you add layouts with setContentView, views within that layouts get freshly instanciated. The ListActivity has a very simple Layout by default (read about it here), even if you don't add your own layout. So basically in your first example:
First you add a listener to the default ListView within the ListActivity
Then you throw that ListView away by using setContentView to instanciate a new layout with a new ListView
Then you never register a new listener to the new ListView from your new layout.
Whereas when you pull setContentView up in your code you only ever work with your own ListView and everything works as expected.
Move your setContentView(lv); right after retrieving the ListView
ListView lv = getListView();
setContentView(lv);
lv.setTextFilterEnabled(true);