I can not figure out what going wrong with my ListView, because it is too small. I want bigger items like default list views on Android.
SelectContactActivity
public class SelectContactActivity extends Activity {
private ArrayList<Contact> listContacts = new ArrayList<Contact>();
private ArrayList<SongInfo> listSong = new ArrayList<SongInfo>();
private ListContactsAdapter adapter;
private Util util = new Util();
private ListView list;
private EditText txt_search;
private ArrayList<Contact> listSearch;
private Handler guiThread;
private Runnable updateTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.setContentView(R.layout.mycontacts);
list = (ListView)findViewById(R.id.list);
txt_search = (EditText)findViewById(R.id.txt_search);
final int position = this.getIntent().getIntExtra("position", 0);
listSong = util.getAllSong(this);
listContacts = util.getAllContact(this);
Log.i("LOG", "Size: " + listContacts.size());
adapter = new ListContactsAdapter(this, android.R.layout.simple_list_item_1, listContacts);
list.setAdapter(adapter);
list.setTextFilterEnabled(true);
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
util.assignRingtoneToContact(SelectContactActivity.this,
listSong.get(position), listContacts.get(arg2));
Toast.makeText(
SelectContactActivity.this,
"Ringtone set successfully",
Toast.LENGTH_LONG).show();
finish();
}
});
innitThread();
txt_search.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
queueUpdate(500);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
private void queueUpdate(long delayMillisecond) {
guiThread.removeCallbacks(updateTask);
// update data if no change in textSearch after time config
// timer by = milliseconds
guiThread.postDelayed(updateTask, delayMillisecond);
}
private void innitThread() {
guiThread = new Handler();
updateTask = new Runnable() {
#Override
public void run() {
String word = txt_search.getText().toString().trim();
if (word.equalsIgnoreCase("")) {
// if not change set listView first
list.setAdapter(new ListContactsAdapter(SelectContactActivity.this,
android.R.layout.simple_list_item_1, listContacts));
} else
// if txtSearch not null
{
// get data from webservice
getDataByKeywords(word);
// Show on list
listSearch = new ArrayList<Contact>();
// get data from webservice
listSearch = getDataByKeywords(word);
list.setAdapter(new ListContactsAdapter(SelectContactActivity.this, android.R.layout.simple_list_item_1, listSearch));
adapter.notifyDataSetChanged();
}
}
};
}
public ArrayList<Contact> getDataByKeywords(String keyword) {
listSearch = new ArrayList<Contact>();
keyword = keyword.toUpperCase();
for (int i = 0; i < listContacts.size(); i++) {
String contain = listContacts.get(i).getName().toUpperCase();
if (contain.contains(keyword)) {
listSearch.add(listContacts.get(i));
}
}
return listSearch;
}
}
ListContactsAdapter
public class ListContactsAdapter extends ArrayAdapter<Contact>{
private ArrayList<Contact> contacts;
private Context context;
public ListContactsAdapter(Context context, int textViewResourceId,
ArrayList<Contact> objects) {
super(context, textViewResourceId, objects);
this.context = context;
this.contacts = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if(convertView!=null){
convertView.setBackgroundResource(R.drawable.list_selector);
}
TextView textView = getGenericView();
textView.setBackgroundResource(R.drawable.list_selector);
textView.setText(contacts.get(position).getName());
return textView;
}
public TextView getGenericView() {
// Layout parameters for the ExpandableListView
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, 70);
TextView textView = new TextView(context);
textView.setLayoutParams(lp);
// Center the text vertically
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
// Set the text starting position
textView.setPadding(16, 0, 0, 0);
textView.setTextSize(18);
textView.setShadowLayer(1, 1, 1, Color.BLACK);
textView.setTextColor(0xffeeeeee);
return textView;
}
}
mycontacts.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<RelativeLayout
android:id="#id/relativeLayoutSearch"
android:layout_width="fill_parent"
android:layout_height="55dp"
android:gravity="center_vertical"
android:paddingLeft="12dp"
android:paddingRight="12dp" >
<EditText
android:id="#id/txt_search"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:background="#drawable/search_bar"
android:hint="#string/hint_apps_search"
android:paddingBottom="12dp"
android:paddingLeft="45.0dip"
android:paddingRight="14dp"
android:paddingTop="12dp"
android:singleLine="true"
android:textSize="15.0sp" />
<Button
android:id="#id/button2"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#drawable/zoomicon" />
</RelativeLayout>
<ListView
android:id="#id/list"
style="#style/ContactList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#id/relativeLayoutSearch"
android:cacheColorHint="#e0000000" />
</RelativeLayout>
styles.xml
<style name="ContactList">
<!-- <item name="android:background">#color/listbg</item> -->
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:cacheColorHint">#e0000000</item>
<item name="android:divider">#color/listdiv</item>
<item name="android:dividerHeight">1.0dip</item>
</style>
This is my code for contact list, and here is a screenshot how this looks, but I want bigger items on list. Any suggestions?
Current listview:
I would start smaller, by revisiting your adapter. The ListView itself is very simple - in your activity layout, you set your ListView to be match_parent for both width and height.
The adapter is the component which creates each row, which in ListAdapter, is initiated by the getView() method.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView != null) {
convertView.setBackgroundResource(R.drawable.list_selector);
}
TextView textView = getGenericView();
textView.setBackgroundResource(R.drawable.list_selector);
textView.setText(contacts.get(position).getName());
return textView;
}
Note what you're doing here is incorrect; you do something to convertView but then you ignore it, and just make a new View. The pattern is more like:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
if (rowView == null) {
rowView = // create a new View that represents your row
}
// bind the data to rowView, then return it
return rowView;
}
which in your case might be:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView rowView = (TextView) convertView;
if (rowView == null) {
rowView = getGenericView();
rowView.setBackgroundResource(R.drawable.list_selector);
}
rowView.setText(contacts.get(position).getName());
return rowView;
}
See, you only need to create rowView if it's null. Also, the background only needs to be set once (and this can be done in XML if you want).
With creating the row View, I'd recommend starting by inflating a layout that contains a single TextView as the only element.
view_item_contact.xml:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
then your getGenericView() can be renamed to createContactRowView():
private TextView createContactRowView(ViewGroup parent) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
return ((TextView) layoutInflater.inflate(R.layout.view_item_contact, parent, false));
}
From there, you can start to style your row in view_item_contact.xml by adding padding, setting a minimum height, centering the text vertically by applying gravity, etc.
view_item_contact.xml:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:gravity="center_vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:background="#drawable/list_selector" />
In almost all cases, I would avoid creating Views programmatically - always inflate them from XML, so you can separate styles and layout from your logic.
Related
I divide my screen in two parts, one of the parts contain five buttons and another part contain seven ImageView with images. Now I want that ImageView rotate infinite,means, after last image, again images start to come. My XML is
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:baselineAligned="true"
tools:context="in.example.splitapp.MainActivity" >
<ScrollView
android:id="#+id/scrollView"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_weight="1"
>
<RelativeLayout
android:id="#+id/linearLayout1"
android:orientation="vertical"
android:layout_weight="1"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:background="#android:color/holo_green_dark">
<Button android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:text="DOG"/>
<Button android:id="#+id/button2"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_below="#id/button1"
android:text="CAT"/>
<Button android:id="#+id/button3"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_below="#id/button2"
android:text="COW"/>
<Button android:id="#+id/button4"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_below="#id/button3"
android:text="RAT"/>
<Button android:id="#+id/button5"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_below="#id/button4"
android:text="PARROT"/>
</RelativeLayout>
</ScrollView>
<ScrollView
android:id="#+id/scrollView2"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_weight="1"
>
<RelativeLayout
android:id="#+id/linearLayout2"
android:orientation="horizontal"
android:layout_weight="1"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:background="#android:color/holo_purple"
>
<ImageView android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:background="#drawable/dog"
android:text="DOG"/>
<ImageView android:id="#+id/imageView2"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_below="#id/imageView1"
android:background="#drawable/cat"
android:text="CAT"/>
<ImageView android:id="#+id/imageView3"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_below="#id/imageView2"
android:background="#drawable/cow"
android:text="COW"/>
<ImageView android:id="#+id/imageView4"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_below="#id/imageView3"
android:background="#drawable/rat"
android:text="RAT"/>
<ImageView android:id="#+id/imageView5"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_below="#id/imageView4"
android:background="#drawable/parrot"
android:text="PARROT"/>
<ImageView android:id="#+id/imageView6"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_below="#id/imageView5"
android:background="#drawable/horse"
android:text="HORSE"/>
<ImageView android:id="#+id/imageView7"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_below="#id/imageView6"
android:background="#drawable/fish"
android:text="FISH"/>
</RelativeLayout>
</ScrollView>
</LinearLayout>
I want that ImageView side scrolling infinite means these five images repeated always.
This is my MainActivity:
public class MainActivity extends Activity implements OnScrollListener {
List<String> animalNameList = new ArrayList<String>();
ArrayList<Integer> animalImageList = new ArrayList<Integer>();
ImageAdapter imageAdapter;
NameAdapter nameAdapter = null;;
boolean flag = false;
ListView listView;
ListView listView1;
ListView upperListView;
RelativeLayout parentLayout;
LinearLayout childLayout;
int index = 0;
UpdateAdapter updateAdapter = null;
ArrayList<DataSplit> array = new ArrayList<DataSplit>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
animalNameList.add("CAT");
animalNameList.add("DOG");
animalNameList.add("COW");
animalNameList.add("RAT");
animalNameList.add("PARROT");
animalNameList.add("HORSE");
animalNameList.add("FISH");
animalImageList.add(R.drawable.horse);
animalImageList.add(R.drawable.parrot);
animalImageList.add(R.drawable.fish);
animalImageList.add(R.drawable.rat);
animalImageList.add(R.drawable.dog);
animalImageList.add(R.drawable.cat);
animalImageList.add(R.drawable.cow);
parentLayout = (RelativeLayout)findViewById(R.id.parentRelative);
childLayout = (LinearLayout)findViewById(R.id.childLinearLayout);
nameAdapter = new NameAdapter(MainActivity.this,
-1, animalNameList);
listView = (ListView)findViewById(R.id.listView1);
listView.setAdapter(nameAdapter);
imageAdapter = new ImageAdapter(MainActivity.this, -1, animalImageList);
listView1 = (ListView)findViewById(R.id.listView2);
CircularListAdapter circularAdapter = new CircularListAdapter(imageAdapter);
listView1.setDivider(null);
listView1.setAdapter(circularAdapter);
listView1.setOnScrollListener(this);
upperListView = (ListView)findViewById(R.id.upperListView);
listView.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
if(flag)
{
}
}
});
}
class NameAdapter extends BaseAdapter {
private List<String> animalName;
private Activity context;
public NameAdapter(Activity context, int textViewResourceId,
List<String> animalName) {
super();
this.animalName = animalName;
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater=context.getLayoutInflater();
convertView = inflater.inflate(R.layout.animalname, parent, false);
Button button=(Button)convertView.findViewById(R.id.button);
button.setId(position);
button.setText(animalName.get(position));
}
return convertView;
}
public int getCount()
{
int size = animalName.size();
return size;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
}
class ImageAdapter extends ArrayAdapter<Integer> {
private ArrayList<Integer> animalImage;
private Activity context;
public ImageAdapter(Activity context, int textViewResourceId,
ArrayList<Integer> animalImage) {
super(context, textViewResourceId);
this.animalImage = animalImage;
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if(view == null) {
view = new View(MainActivity.this);
}
view.setId(position);
//view.setBackgroundResource(animalImage[position]);
view.setBackgroundResource(animalImage.get(position));
return view;
}
public int getCount()
{
int size = animalImage.size();
return size;
}
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
int childInt = view.getChildAt(0).getId();
//String img1Text = this.getResources().getResourceEntryName(animalImage[childInt]);
String img1Text = this.getResources().getResourceEntryName(animalImageList.get(childInt));
//String buttonText = animalName[index];
String buttonText = animalNameList.get(index);
if(img1Text.equalsIgnoreCase(buttonText))
{
final String name = animalNameList.get(index);
int image = animalImageList.get(childInt);
DataSplit data = new DataSplit();
data.setAnimalName(name);
data.setAnimalImage(image);
array.add(data);
index++;
flag = true;
if(array.size() == 1)
{
updateAdapter = new UpdateAdapter(MainActivity.this,-1,array);
upperListView.setAdapter(updateAdapter);
upperListView.setVisibility(View.VISIBLE);
}
else
{
updateAdapter.notifyDataSetChanged();
}
listView.post(new Runnable() {
#Override
public void run() {
animalNameList.remove(name);
nameAdapter.notifyDataSetChanged();
}
});
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
class UpdateAdapter extends ArrayAdapter<Integer> {
ArrayList<DataSplit> dataSplit;
private Activity context;
public UpdateAdapter(Activity context, int textViewResourceId,
ArrayList<DataSplit> dataSplit) {
super(context, textViewResourceId);
this.dataSplit = dataSplit;
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater=context.getLayoutInflater();
convertView = inflater.inflate(R.layout.addeddata, parent, false);
Button button=(Button)convertView.findViewById(R.id.button);
ImageView imageView=(ImageView)convertView.findViewById(R.id.imageView);
String animalName = dataSplit.get(position).getAnimalName();
int imageName = dataSplit.get(position).getAnimalImage();
button.setText(dataSplit.get(position).getAnimalName());
imageView.setBackgroundResource(dataSplit.get(position).getAnimalImage());
}
return convertView;
}
public int getCount()
{
int size = dataSplit.size();
return size;
}
}
}
I created activity_main.xml which contains a parent RelativeLayout and under this a ListView named upperListView and initially set visibility gone. Below this I created a LinearLayout and for this I created two ListView for Name DataSet and Image DataSet. When data matches I create a UpdateAdapter in which I use addeddata.xml, in which a button and ImageView created and when it is a successful match then hidden list view visibility becomes Visible and this "addeddata.xml" loaded in listview. This I perform. It will work perfectly.But when first matches,i.e, CAT name match with the Cat image, data is not deleted from both of listview and CAT name again shown in below the new ListView.
How to manage to complete matches if the application crashes.
This has been discussed in the past, with using circular Listviews:
How to create a closed (circular) ListView?
Closed or circular Horizontal ListView Android
I just want when I scroll ImageView part then if Dog image matches with the right end side Dog name then image stick with the Dog Name Button and rest of the images remain scrolling.
For this here is what you could try:
after scrolling items in list1 and list2, iterate over each item in the shortest listview and check if item1(position) [tag] = item2(position) [tag] (so, if you have a match)
if true:
redraw screen like this: add a new listview at the bottom of the screen (below both listviews). This listview with contain both item1 and item2 (so it's litviewitem xml will be a linear layout with other two linear layouts, one containing the matched pet name and the other the matched pet picture)
remove item1(position) and item2(position) from listview1, listview2 (which means you have to remove, for example, dog name from listview pet names datasource, and dog image from listview pet pictures datasource and reset adapters to listviews)
this way you will continue to be able to scroll and match items from listview1 and listview2 - without the already matching items-, and also have a bottom listview with all the matching elements that cannot be matched any more
Hope this helps!
After spend couple of days I found the perfect solution for my question. I dynamically created the ImageView and also the ListView. Image data are populating in the ListView. After matching the text with right Image, I take that ImageView from the List and set in dynamically created ImageView. Following is my code.
public class MainActivity extends Activity implements OnScrollChangedListener, OnScrollListener{
int index = 0;
ImageView imageView1;
List<Integer> spectrum = new ArrayList<Integer>();
String[] animalName;
ImageView[] imageArray;
Button[] buttonArray;
ListView listView;
SpectrumAdapter spectrumAdapter;
ListView animalImage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
animalName = new String[]{"CAT","DOG","COW","RAT","PARROT","HORSE","FISH"};
imageArray = new ImageView[animalName.length];
buttonArray = new Button[animalName.length];
LinearLayout inner1 = (LinearLayout)findViewById(R.id.innerLayout1);
LinearLayout inner2 = (LinearLayout)findViewById(R.id.innerLayout2);
ListView animalList = (ListView)findViewById(R.id.animalList);
NameAdapter nameAdapter = new NameAdapter(MainActivity.this,
-1, animalName);
animalList.setAdapter(nameAdapter);
for(int i=0;i<animalName.length;i++)
{
ImageView imageView = new ImageView(this);
imageView.setId(i);
RelativeLayout.LayoutParams params1 = new RelativeLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,150);
imageView.setTag(i);
imageView.setLayoutParams(params1);
imageView.setVisibility(View.GONE);
imageArray[i] = imageView;
inner1.addView(imageView);
}
ListView listView = new ListView(this);
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
listView.setLayoutParams(param);
inner2.addView(listView);
spectrum.add(R.drawable.horse);
spectrum.add(R.drawable.rat);
spectrum.add(R.drawable.cow);
spectrum.add(R.drawable.dog);
spectrum.add(R.drawable.fish);
spectrum.add(R.drawable.parrot);
spectrum.add(R.drawable.cat);
spectrumAdapter = new SpectrumAdapter(MainActivity.this,
-1, spectrum);
CircularListAdapter circularAdapter = new CircularListAdapter(spectrumAdapter);
listView.setAdapter(circularAdapter);
listView.setOnScrollListener(this);
}
class NameAdapter extends BaseAdapter {
private String[] animalName;
private Activity context;
public NameAdapter(Activity context, int textViewResourceId,
String[] animalName) {
super();
this.animalName = animalName;
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater=context.getLayoutInflater();
convertView = inflater.inflate(R.layout.animalname, parent, false);
}
Button button=(Button)convertView.findViewById(R.id.button);
button.setText(animalName[position]);
return convertView;
}
public int getCount()
{
int size = animalName.length;
return size;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
}
class SpectrumAdapter extends ArrayAdapter<Integer> {
private List<Integer> spectrum;
public SpectrumAdapter(Context context, int textViewResourceId,
List<Integer> spectrum) {
super(context, textViewResourceId, spectrum);
this.spectrum = spectrum;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if(view == null) {
view = new View(MainActivity.this);
}
view.setId(position);
view.setBackgroundResource(spectrum.get(position));
return view;
}
public int getCount()
{
int size = spectrum.size();
return size;
}
}
#Override
public void onScrollChanged() {
// TODO Auto-generated method stub
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
int childInt = view.getChildAt(0).getId();
String img1Text = this.getResources().getResourceEntryName(spectrum.get(childInt));
String bb = animalName[index];
if(bb.equalsIgnoreCase(img1Text))
{
ImageView img = imageArray[index];
img.setBackgroundResource(spectrum.get(childInt));
img.setVisibility(View.VISIBLE);
index++;
}
else
{
}
}
}
This is the perfect solution for the question. Thanks all for the suggestion.
I made a listview in a fragment. Now I need to add a simple icon to the listview items. The icon must be the same on every item. This will be a simple arrow (imageview).
Is this possible with the listview I made? And if yes, how do I do it?
So like this format:
My text here --space--space-- >
The code for the fragment:
public class BiblioFragment extends Fragment {
final String[] items = new String[] { "Astma en alcohol", "Astma en huisdieren", "Astma en lichaamsgewicht",
"Astma en ouder worden", "Astmamedicatie", "Bekende mensen met astma", "Longfunctieonderzoek", "Reizen en vakantie",
"Sociaal leven", "Weetjes over astma", "Enzovoort", "Enzovoort", "Enzovoort" };
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_biblio, container, false);
ListView list = (ListView)view.findViewById(R.id.listView1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, items);
list.setAdapter(adapter);
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
Log.v("TAG", "CLICKED row number: " + arg2);
Intent myIntent = new Intent(getActivity(), BiblioDetail.class);
myIntent.putExtra("welkerij", arg2);
startActivity(myIntent);
}
});
return view;
}
}
My XML for that fragment:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#ffffff">
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ListView>
</LinearLayout>
In onCreateView
ListView list = (ListView)view.findViewById(R.id.listView1);
CustomAdapter cus = new CustomAdapter(getActivity(),items);
list.setAdapter(cus);
Use a custom adapter
public class CustomAdapter extends BaseAdapter {
String items[];
LayoutInflater mInflater;
public CustomAdapter(Context context, String[] items) {
mInflater = LayoutInflater.from(context);
this.items = items;
}
#Override
public int getCount() {
return items.length;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView ==null)
{
convertView = mInflater.inflate(R.layout.list_item,parent,false);
holder = new ViewHolder();
holder.tv = (TextView) convertView.findViewById(R.id.textView1);
holder.iv = (ImageView) convertView.findViewById(R.id.imageView1);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.tv.setText(items[position])
// use holder.iv to set whatever image you want according to the position
return convertView;
}
static class ViewHolder
{
ImageView iv;
TextView tv;
}
}
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="42dp"
android:layout_marginTop="32dp"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/imageView1"
android:layout_marginLeft="64dp"
android:layout_marginTop="14dp"
android:layout_toRightOf="#+id/imageView1"
android:text="TextView" />
</RelativeLayout>
Snap
Edit:
If you feel this is over kill you can use a compound textview with image on the left and text on the right.
In the above I have used list_item.xml which is a custom layout. I inflate that layout in getView of custom adapter. I set the text to textview. I have set the default launcher icon to imageview. You can change it though.
I have also used a ViewHolder
http://developer.android.com/training/improving-layouts/smooth-scrolling.html
Also check
How ListView's recycling mechanism works
Create ListAdapter
public class ListAdapter extends ArrayAdapter<Item> {
public ListAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
// TODO Auto-generated constructor stub
}
private List<Item> items;
public ListAdapter(Context context, int resource, List<Item> items) {
super(context, resource, items);
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.itemlistrow, null);
}
Item p = items.get(position);
if (p != null) {
ImageView ICon = ( ImageView) v.findViewById(R.id.description);
}
}
return v;
}
In your Activity
ListView yourListView = (ListView) findViewById(R.id.itemListView);
// get data from the table by the ListAdapter
ListAdapter customAdapter = new ListAdapter(this, R.layout.itemlistrow, List<yourItem>);
yourListView .setAdapter(customAdapter);
I used the following code create a custom listview ....But the problem with this code it it is selecting only one item..but highlighting many items...i mean ..for example..if i have 8 items in the list..And i can see only 3 items(rest i have to scroll to see)..if i click the first item...it gets highlighted along with the fourth and the 7th item...
public class MainMenu extends Activity {
ListView lmenu;
View v1;
String s;
Class<?> ourclass;
View layout, row;
static int trantype;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.menulist);
Menu Menu_data[] = new Menu[] { new Menu("1.White"),
new Menu("2.Blue"), new Menu("3.Purple"), new Menu("4.Red"),
new Menu("5.Yellow"), new Menu("6.Black"), new Menu("6.Black"),
new Menu("6.Black"), new Menu("6.Black"), new Menu("6.Black"),
new Menu("6.Black"), new Menu("6.Black") };
MenuAdapter adapter = new MenuAdapter(this, R.layout.menutext,
Menu_data);
lmenu = (ListView) findViewById(R.id.mainmenu);
lmenu.setAdapter(adapter);
lmenu.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> ada, View v, int position,
long id) {
// TODO Auto-generated method stub
/*
* v.setBackgroundColor(Color.parseColor("#FCD5B5")); if (!(v1
* == null) && v1 != v)
* v1.setBackgroundColor(Color.parseColor("#EEEEEE")); v1 = v;
*/
Intent swipeit = new Intent(getBaseContext(), Swipeit.class);
trantype = position + 1;
startActivity(swipeit);
}
});
findViewById(R.id.BLogout).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
}
public class Menu {
public String title;
public Menu() {
super();
}
public Menu(String title) {
super();
this.title = title;
}
}
public class MenuAdapter extends ArrayAdapter<Menu> {
Context context;
int layoutResourceId;
Menu data[] = null;
LayoutInflater inflater;
boolean[] arrBgcolor;
private int activeHex, inactiveHex;
public MenuAdapter(Context context, int layoutResourceId, Menu[] data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
activeHex = Color.parseColor("#FCD5B5");
inactiveHex = Color.parseColor("#EEEEEE");
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
arrBgcolor = new boolean[13];
}
#Override
public View getView(final int position, final View convertView,
ViewGroup parent) {
try {
MenuHolder holder = null;
row = convertView;
// convertView.setBackgroundColor(Color.BLACK);
if (row == null) {
LayoutInflater inflater = ((Activity) context)
.getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new MenuHolder();
holder.txtTitle = (TextView) row.findViewById(R.id.tv1);
row.setTag(holder);
} else {
holder = (MenuHolder) row.getTag();
}
Menu Menu = data[position];
holder.txtTitle.setText(Menu.title);
holder.txtTitle.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
resetArrbg();
arrBgcolor[position] = true;
if (arrBgcolor[position]) {
row.setBackgroundColor(activeHex);
} else {
row.setBackgroundColor(inactiveHex);
}
notifyDataSetChanged();
}
});
} catch (Exception e) {
Toast.makeText(getApplicationContext(), String.valueOf(e),
Toast.LENGTH_LONG).show();
}
return row;
}
private void resetArrbg() {
for (int i = 0; i < arrBgcolor.length; i++) {
arrBgcolor[i] = false;
}
}
public class MenuHolder {
TextView txtTitle;
}
}
}
my xml containing list...
<include
android:id="#+id/header"
android:layout_alignParentTop="true"
layout="#layout/header" />
<RelativeLayout
android:id="#+id/Rlmain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/header"
android:orientation="vertical" >
<TextView
android:id="#+id/TMain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginBottom="8dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="8dp"
android:text="Main Menu"
android:textColor="#000000"
android:textSize="15dp" />
<View
android:id="#+id/Vtop"
android:layout_width="fill_parent"
android:layout_height="2dp"
android:layout_below="#+id/TMain"
android:background="#android:color/darker_gray" />
</RelativeLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#+id/Vbot"
android:layout_below="#+id/Rlmain"
android:orientation="vertical" >
<ListView
android:id="#+id/mainmenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#E0E0E0"
android:cacheColorHint="#00000000"
android:divider="#android:color/transparent"
android:dividerHeight="20dp" >
</ListView>
</RelativeLayout>
<View
android:id="#+id/Vbot"
android:layout_width="fill_parent"
android:layout_height="2dp"
android:layout_above="#+id/textView1"
android:background="#android:color/darker_gray" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="© India Transact Services Ltd."
android:textColor="#000000"
android:textSize="15dp" />
</RelativeLayout>
my xml for list....
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LLtv"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#EEEEEE"
android:cacheColorHint="#00000000" >
<TextView
android:id="#+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingBottom="12dp"
android:paddingTop="12dp"
android:textColor="#000000"
android:textSize="20dp" />
</LinearLayout>
Can please anyone help me and tell where i am going wrong?
What you want can't be achieved with your current setup. You need to implement a custom adapter where you have access to the getView() method. For reasons made clearer in the answer here, what you need to do is use some sort of data-container that will hold the status of an individual row using some indicator and then perform your action based on it's position on the container (which should correspond to its position on the listview)
for example, check out this re-write:
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
resetArrbg();
arrBgcolor[position] = true;
if (arrBgcolor[position]) {
v.setBackgroundColor(Color.parseColor("#FCD5B5"));
} else {
v.setBackgroundColor(Color.BLUE);
}
}
boolean[] arrBgcolor = new boolean[list.size()];
private void resetArrbg() {
for (int i = 0; i < arrBgcolor.length; i++) {
arrBgcolor[i] = false;
}
}
Does it make sense now why it can't work with the current set-up? The else part of the method, the part affecting the other views, can never take place because you don't have access to the other positions in the onListItemClick method, but you do in getView(). This is of course, unless you know of a way around this then, by all means, more power to you. all the same i don't think the v1 technique do you any good.
EDIT:
public class MainActivity extends Activity {
ListView lmenu;
View v1;
String s;
Class<?> ourclass;
View layout, row;
static int trantype;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.menulist);
Menu Menu_data[] = new Menu[] { new Menu("1.White"),
new Menu("2.Blue"), new Menu("3.Purple"), new Menu("4.Red"),
new Menu("5.Yellow"), new Menu("6.Black"), new Menu("6.Black"),
new Menu("6.Black"), new Menu("6.Black"), new Menu("6.Black"),
new Menu("6.Black"), new Menu("6.Black") };
MenuAdapter adapter = new MenuAdapter(this, R.layout.menutext, Menu_data);
lmenu = (ListView) findViewById(R.id.mainmenu);
lmenu.setAdapter(adapter);
}
public class Menu {
public String title;
public Menu() {
super();
}
public Menu(String title) {
super();
this.title = title;
}
}
public class MenuAdapter extends ArrayAdapter<Menu> {
Context context;
int layoutResourceId;
Menu data[];
LayoutInflater inflater;
boolean[] arrBgcolor;
private int activeHex, inactiveHex;
public MenuAdapter(Context context, int layoutResourceId, Menu[] data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
activeHex = Color.parseColor("#FCD5B5");
inactiveHex = Color.parseColor("#EEEEEE");
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
arrBgcolor = new boolean[data.length];
resetArrbg();
}
#Override
public View getView(final int position, final View convertView,
ViewGroup parent) {
final MenuHolder holder;
row = convertView;
// convertView.setBackgroundColor(Color.BLACK);
if (row == null) {
row = inflater.inflate(layoutResourceId, parent, false);
holder = new MenuHolder();
holder.txtTitle = (TextView) row.findViewById(R.id.tv1);
row.setTag(holder);
} else {
holder = (MenuHolder) row.getTag();
}
Menu Menu = data[position];
holder.txtTitle.setText(Menu.title);
if (arrBgcolor[position]) {
row.setBackgroundColor(activeHex);
} else {
row.setBackgroundColor(inactiveHex);
}
holder.txtTitle.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
resetArrbg();
arrBgcolor[position] = true;
notifyDataSetChanged();
}
});
return row;
}
private void resetArrbg() {
for (int i = 0; i < arrBgcolor.length; i++) {
arrBgcolor[i] = false;
}
}
public class MenuHolder {
TextView txtTitle;
}
}
}
This happens because of the way ListView reuses Views when populating the list. Lets say you see three rows of the list at any given time. You "highlight" the first row by setting the background color (like you do), and scroll down. When the first row leaves the screen, Android does something smart. Instead of creating a new View for, say, the fifth row, it reuses the View from row one. That's the View you changed the background color of, so row five now got the same background color. Only the data is changed.
As for how to implement a different background color on the selected row, and the selected row only, have a look at this answer. I do believe you got to implement a custom ListAdapter, at least if you're developing for API levels lower than 11.
I'm trying to place a spinner inside a list view item in android. The problem is this seems to prevent the row from being highlighted during a press and the onItemClickListener is not getting called by the ListView. Basically I am trying to mimic the functionality in the Google Music app. Does anyone know how to do this? This is the code I have been trying (I know it may not be the best... just throwing together a quick sample which shows the problem):
Activity:
public class ListViewTestActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView listView = (ListView) findViewById(R.id.listView1);
DataHolder data = new DataHolder(this);
DataHolder data1 = new DataHolder(this);
DataHolder data2 = new DataHolder(this);
DataHolder data3 = new DataHolder(this);
DataHolder data4 = new DataHolder(this);
DataAdapter d = new DataAdapter(this, R.layout.rowview, new DataHolder[] { data, data1, data2, data3, data4 });
listView.setAdapter(d);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Log.e("ERROR", "look at me!");
}
});
}
}
public class DataHolder {
private int selected;
private ArrayAdapter<CharSequence> adapter;
public DataHolder(Context parent) {
adapter = ArrayAdapter.createFromResource(parent, R.array.choices, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
}
public ArrayAdapter<CharSequence> getAdapter() {
return adapter;
}
public String getText() {
return (String) adapter.getItem(selected);
}
public int getSelected() {
return selected;
}
public void setSelected(int selected) {
this.selected = selected;
}
}
This is the list adapter:
public class DataAdapter extends ArrayAdapter<DataHolder> {
private Activity myContext;
public DataAdapter(Activity context, int textViewResourceId, DataHolder[] objects) {
super(context, textViewResourceId, objects);
myContext = context;
}
// We keep this ViewHolder object to save time. It's quicker than findViewById() when repainting.
static class ViewHolder {
protected DataHolder data;
protected TextView text;
protected Spinner spin;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
// Check to see if this row has already been painted once.
if (convertView == null) {
// If it hasn't, set up everything:
LayoutInflater inflator = myContext.getLayoutInflater();
view = inflator.inflate(R.layout.rowview, null);
// Make a new ViewHolder for this row, and modify its data and spinner:
final ViewHolder viewHolder = new ViewHolder();
viewHolder.text = (TextView) view.findViewById(R.id.text);
viewHolder.data = new DataHolder(myContext);
viewHolder.spin = (Spinner) view.findViewById(R.id.spin);
viewHolder.spin.setAdapter(viewHolder.data.getAdapter());
// Used to handle events when the user changes the Spinner selection:
viewHolder.spin.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
viewHolder.data.setSelected(arg2);
viewHolder.text.setText(viewHolder.data.getText());
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
Log.d("DBGINF", "asdf");
}
});
// Update the TextView to reflect what's in the Spinner
viewHolder.text.setText(viewHolder.data.getText());
view.setTag(viewHolder);
Log.d("DBGINF", viewHolder.text.getText() + "");
} else {
view = convertView;
}
// This is what gets called every time the ListView refreshes
ViewHolder holder = (ViewHolder) view.getTag();
holder.text.setText(getItem(position).getText());
holder.spin.setSelection(getItem(position).getSelected());
return view;
}
}
Main layout for activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<ListView android:id="#+id/listView1" android:layout_height="match_parent" android:layout_width="match_parent" />
</LinearLayout>
Layout for a row:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content" android:weightSum="1" >
<TextView android:layout_width="wrap_content"
android:layout_height="match_parent" android:id="#+id/text"
android:layout_weight="0.5" android:textSize="25sp" />
<Spinner android:layout_width="0dp" android:layout_height="wrap_content"
android:id="#+id/spin" android:prompt="#string/choice_prompt"
android:layout_weight="0.5" />
</LinearLayout>
Thanks for any help!
I had the same problem with ImageButton, and what was needed was to do
mImageButton.setFocusable(false);
I can't garantee it's the same for Spinner, but my money is on it.
Best regards.
I have a ListView with EditText inside.
Actually, when i touch an element of the Listview, the EditText have the focus and the keyboard appeared. Good.
The problem is i wanna do something on this EditText throught the listView's onItemClickListener, but seems that my code never enter in this method.
I try some setDescendantFocusability to my Listview but don't solve the problem.
Thanks a lot.
public class NoteAdapter extends BaseAdapter {
private ArrayList<String> notes;
private LayoutInflater inflater;
private Context context;
public NoteAdapter(Context context, ArrayList<String> notes) {
inflater = LayoutInflater.from(context);
this.notes = notes;
this.context = context;
}
public int getCount() {
// TODO Auto-generated method stub
return notes.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return notes.get(position);
}
public long getItemId(int id) {
// TODO Auto-generated method stub
return id;
}
private class ViewHolder {
EditText note;
}
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder;
if(convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.listenote, null);
holder.note = (EditText)convertView.findViewById(R.id.note);
convertView.setTag(holder);
}else {
holder= (ViewHolder) convertView.getTag();
}
holder.note.setText(notes.get(position));
return convertView;
}
}
my main activity
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
notes = new ArrayList<String>();
for(int i=0; i< 10; i++)
notes.add("note"+i);
EditTextSelected = null;
adapter = new NoteAdapter(this, notes);
lv1 = ((ListView)findViewById(R.id.listeNote));
lv1.setAdapter(adapter);
lv1.setClickable(true);
lv1.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
Toast t = Toast.makeText(FastItActivity.this, "hello", 200);
t.show();
}
});
listenote.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
android:id="#+id/widget1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<EditText
android:id="#+id/note"
android:textColor="#color/black"
android:textSize="12dp"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:padding="5dp"
android:inputType="textMultiLine"
android:scrollHorizontally="false"
android:gravity="top|left"
android:ems="10"
android:layout_margin="10dp"
android:background="#drawable/fond_note"
/>
</TableLayout>
main.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
android:id="#+id/widget1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#drawable/wooden_top"
>
<ListView
android:id="#+id/listeNote"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#android:color/transparent"
android:cacheColorHint="#00000000"
android:isScrollContainer="false"
android:divider="#00000000"
>
</ListView>
</TableLayout>
Move your modifications from ListView's onItemClickListener to your EditText's onClickListener
In NoteAdapter's getView:
holder.note = (EditText)convertView.findViewById(R.id.note);
holder.note.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//do something
}
});
or try this:
holder.note.setOnFocusListener(new View.OnFocusListener(){
#Override
public void onFocus(){
//do something
}
}
getView method has position parameter so you'll be able to distinguish what EditText was clicked (if you need different actions with different EditTexts)
This article is pretty long but towards the middle/end he demonstrates an interactive listview which is exactly what you need. http://www.vogella.de/articles/AndroidListView/article.html
If you could post some code that would help.
I was trying to solve a similar problem: which item in a list was selected when you embed several views in list item?!
I refuse to create a new listener for each item in the list. I can't imagine that would scale well on such a resource constrained platform. But, I found you can solve this problem by specializing EditText to set and retrieve the selected index in onClick.
Define your specialization:
package userInterface;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.EditText;
public class IndexedEditText extends EditText {
public int listIndex;
public IndexedEditText(Context context) {
super(context);
}
public IndexedEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public IndexedEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
}
Replace your EditText for your specialized class in the list item XML declaration. Be sure to get the path to your new class right (in my case it's userInterface.IndexedEditText).
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<userInterface.IndexedEditText
android:id="#+id/et_first_item"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:hint="#string/select"
android:inputType="none" />
<!-- other views -->
</RelativeLayout>
Set listIndex in getView, and set your OnClickListener for each IndexedEditText instance:
public abstract class EditTextPairArrayAdapter <T> extends ArrayAdapter<T> {
LayoutInflater inflater;
static class ViewHolder {
private WeakReference<IndexedEditText> name;
private WeakReference<EditText> notes;
public ViewHolder(IndexedEditText tv, EditText et) {
name = new WeakReference<IndexedEditText>(tv);
notes = new WeakReference<EditText>(et);
}
}
int textViewId;
int editTextId;
int listItemId;
List<T> list = null;
WeakReference<Context> contextRef;
//context is Activity that instantiates this array adapter
//resourceId is the layout xml ID for your special row
//textViewResourceId is any TextView ID in your special row xml def
//editTextResourceId means nothing in this context
//objects is the initial list of objects to present in UI
public EditTextPairArrayAdapter(Context context, int resourceId, int textViewResourceId, int editTextResourceId, List<T> objects) {
super(context, resourceId, textViewResourceId, objects);
this.listItemId = resourceId;
this.textViewId = textViewResourceId;
this.editTextId= editTextResourceId;
this.list = objects;
this.contextRef = new WeakReference<Context>(context);
}
#Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
View view = null;
ViewHolder viewHolder = null;
if (convertView == null) {
if(inflater == null)
inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(listItemId, null);
IndexedEditText text = (IndexedEditText)view.findViewById(textViewId);
EditText notes = (EditText) view.findViewById(editTextId);
text.listIndex = position;
//Special sauce
if(contextRef != null && contextRef.get() != null && (contextRef.get() instanceof View.OnClickListener)) {
text.setOnClickListener((View.OnClickListener) contextRef.get());
}
viewHolder = new ViewHolder(text, notes);
view.setTag(viewHolder);
}
else {
view = convertView;
viewHolder = (ViewHolder) convertView.getTag();
}
Titem = this.getItem(position);
if(item != null) {
//special sauce
}
return view;
}
//add abstract methods for implementations to define special sauce
}
Finally, in your Activity that implements OnClickListener:
public void onClick(View v) {
if(v instanceof IndexedEditText) {
Object obj = myList.get(((IndexedEditText)v).listIndex);
//do stuff with obj
}
}
The solution I found is to superimpose an EditText with a TextView and alternate gone/visible on both so that the EditText stops inducing bugs when hidden.