I apologize for my English. I thought a few days how to make a spinner in the ListView, and I was able to do it. But now I do not know how to take data from the spinner. I ask please tell me how to take the data from each spinner in ListView
activity_main.xml
<RelativeLayout
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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<ListView
android:id="#+id/lvCustomList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
loyout_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="10dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<Spinner
android:id="#+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
MainActivity
ListView lvDetail;
Button btn;
Context context = MainActivity.this;
ArrayList myList = new ArrayList();
String[] nameQuestions = new String[] {
"question1", "question2", "questions3",
"questions4", "questions5"
};
ArrayList<HashMap<String, String>> listArray = new ArrayList<HashMap<String, String>>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lvDetail = (ListView) findViewById(R.id.lvCustomList);
btn = (Button) findViewById(R.id.sendQuestions);
getDataInList();
lvDetail.setAdapter(new MyBaseAdapter(context, myList));
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//how get value all spinners?
}
});
}
private void getDataInList() {
for(int i=0;i<4;i++) {
ListData ld = new ListData();
ld.setQuestions(nameQuestions[i]);
myList.add(ld);
}
}
}
ListData
public class ListData {
String questions;
public String getQuestions() {
return questions;
}
public void setQuestions(String questions) {
this.questions = questions;
}
}
MyBaseAdapter
public class MyBaseAdapter extends BaseAdapter {
ListData ld = new ListData();
ArrayList<ListData> myList = new ArrayList<ListData>();
LayoutInflater inflater;
Context context;
String cardStatusString;
ArrayList<String> spinnerArray = new ArrayList<String>();
public MyBaseAdapter(Context context, ArrayList myList) {
this.myList = myList;
this.context = context;
inflater = LayoutInflater.from(this.context);
spinnerArray.add("1");
spinnerArray.add("2");
spinnerArray.add("3");
spinnerArray.add("4");
spinnerArray.add("5");
}
#Override
public int getCount() {
return myList.size();
}
#Override
public ListData getItem(int position) {
return myList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
MyViewHolder mViewHolder;
if(convertView == null) {
convertView = inflater.inflate(R.layout.layout_list_item, null);
mViewHolder = new MyViewHolder();
convertView.setTag(mViewHolder);
} else {
mViewHolder = (MyViewHolder) convertView.getTag();
}
mViewHolder.sp = spinnerDetails(convertView, R.id.spinner, myList.get(position).getQuestions());
mViewHolder.nameText = nameDetails(convertView, R.id.nameText, myList.get(position).getQuestions());
return convertView;
}
private TextView nameDetails(View v, int resId, String text) {
TextView nameText = (TextView) v.findViewById(resId);
nameText.setText(text);
return nameText;
}
//this is create spinner
private Spinner spinnerDetails(View v, int resId, String text) {
Spinner mySpinner = (Spinner) v.findViewById(resId);
#SuppressWarnings({ "unchecked", "rawtypes" })
ArrayAdapter spinnerArrayAdapter = new ArrayAdapter(context,
android.R.layout.simple_spinner_dropdown_item,
spinnerArray);
mySpinner.setAdapter(spinnerArrayAdapter);
return mySpinner;
}
private class MyViewHolder {
Spinner sp;
TextView nameText;
}
}
You can iterate over your ListView and collect all the selections into a List as
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
List<String> selections = new ArrayList<String>();
for (int i = 0; i < lvDetail.getChildCount(); i++) {
// Get row's spinner
View listItem = lvDetail.getChildAt(i);
Spinner spinner = (Spinner) listItem.findViewById(R.id.spinner);
// Get selection
String selection = (String) spinner.getSelectedItem();
selections.add(selection);
}
// process selections
}
});
I would say add a method on the Adapter that returns that value to the activity its in, since there is no other way to get the value otherwise, except with getChildAt as Ravi pointed out. But this may need further tweaking too since for ListViews the elements that are not visible in the screen are not loaded (and the spinner value will reset to default), but that depends on what you want this for
Related
Hear i use Custom ListView with TextView and CheckBox.
But i want that Single Selection in CheckBox At a time
One CheckBox Selected then other one is Deselect
using BaseAdapter
but This code not Work Properly ..
Please Give me Suggestion ..thnks
#Override
public View getView(final int position, View view, ViewGroup parent) {
Integer selected_position = -1;
holder = new ViewHolder();
final Items itm = rowItem.get(position);
LayoutInflater layoutInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (view == null) {
view = layoutInflater.inflate(R.layout.activity_custom_list,
parent, false);
holder.tvItemName = (TextView) view.findViewById(R.id.textView1);
holder.check = (CheckBox) view.findViewById(R.id.checkBox1);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.tvItemName.setText(itm.getItems());
if (position == selected_position)
holder.check.setChecked(true);
else
holder.check.setChecked(false);
holder.check.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (holder.check.isChecked()) {
selected_position = position;
} else {
selected_position = -1;
}
notifyDataSetChanged();
}
});
return view;
}}
use Custom List-View with Text-View And Check-Box With Single Selection of Check Box
So many try then finally i got the Solution I hope it is Useful Code to you All...
This code Help you to create custom List-view with Text-view and Check-box then you select one check-box and if you select another one the first should automatically be Deselected.....Thank You...
activity_main.xml
<RelativeLayout 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"
tools:context="com.example.listviewdemo2.MainActivity" >
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
</RelativeLayout>
activity_custom_list.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.listviewdemo2.CustomListActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/darker_gray" >
<TextView
android:id="#+id/textView1"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="4dp"
android:layout_weight="0.39"
android:textAppearance="?android:attr/textAppearanceMedium" />
<CheckBox
android:id="#+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="150dp"
android:layout_marginTop="4dp"/>
</LinearLayout> </LinearLayout>
String.xml
<string-array name="name">
<item>Laptop</item>
<item>Mobile</item>
<item>Desktop</item>
<item>TV</item>
<item>Pendrive</item>
<item>Router</item>
<item>Notebook</item>
<item>Tablet</item>
<item>I-pad</item>
<item>Bluetooth</item>
<item>HomeTheator</item>
</string-array>
MainActivity.java
String[] ItemName;
List<Items> rowItem;
ListView list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rowItem = new ArrayList<Items>();
ItemName = getResources().getStringArray(R.array.name);
for(int i = 0 ; i < ItemName.length ; i++)
{
Items itm = new Items(ItemName[i]);
rowItem.add(itm);
}
list = (ListView) findViewById(R.id.listView1);
CustomListActivity adapter = new CustomListActivity(this, rowItem);
list.setAdapter(adapter);
}
Items.java
public class Items {
private String items;
private boolean selected;
public Items(String items) {
this.items = items;
}
public String getItems() {
return items;
}
public void setItemName(String name) {
this.items = name;
}
public boolean getSelected() {
return selected;
}
public boolean setSelected(Boolean selected) {
return this.selected = selected;
}}
CustomListActivity.java
public class CustomListActivity extends BaseAdapter {
Context context;
List<Items> rowItem;
View listView;
boolean checkState[];
ViewHolder holder;
public CustomListActivity(Context context, List<Items> rowItem) {
this.context = context;
this.rowItem = rowItem;
checkState = new boolean[rowItem.size()];
}
#Override
public int getCount() {
return rowItem.size();
}
#Override
public Object getItem(int position) {
return rowItem.get(position);
}
#Override
public long getItemId(int position) {
return rowItem.indexOf(getItem(position));
}
public class ViewHolder {
TextView tvItemName;
CheckBox check;
}
#Override
public View getView(final int position, View view, ViewGroup parent) {
holder = new ViewHolder();
final Items itm = rowItem.get(position);
LayoutInflater layoutInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (view == null) {
listView = new View(context);
listView = layoutInflater.inflate(R.layout.activity_custom_list,
parent, false);
holder.tvItemName = (TextView) listView
.findViewById(R.id.textView1);
holder.check = (CheckBox) listView.findViewById(R.id.checkBox1);
listView.setTag(holder);
} else {
listView = (View) view;
holder = (ViewHolder) listView.getTag();
}
holder.tvItemName.setText(itm.getItems());
holder.check.setChecked(checkState[position]);
holder.check.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
for(int i=0;i<checkState.length;i++)
{
if(i==position)
{
checkState[i]=true;
}
else
{
checkState[i]=false;
}
}
notifyDataSetChanged();
}
});
return listView;
}}
Show The Output :-
If you want a custom ListView with single choice CheckBox you can use something like this:
https://stackoverflow.com/a/12003125/5778152
I have a custom row item xml and a Activity xml which has a button, a textbox and a listview. Can anybody give me a very simple example on how this is done? I know i will need a adapter (what it extends i dont know) and update it from the button
I have tried getting the list view updated from the button with the editview text but cant get the adapter code to be hit. I am looking at base adapters now but cant help but feel this shouldn't be complicated and need so many override methods.
Activity class
public class InvitePlayers_Activity extends Activity {
ListViewAdapter emailAdapter = null;
ImageView imgView_mail;
ImageView imgView_confirm;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE); //remove title bar
setContentView(R.layout.activity_inviteplayers);
//Generate list View from ArrayList
displayListView();
}
private void displayListView() {
//assign controls
final ListView listView = (ListView) findViewById(R.id.listView_invitePlayers);
imgView_mail = (ImageView)findViewById(R.id.imgView_mail);
//Test data
ArrayList<String> inviteNew = new ArrayList<String>();
final ArrayList<ArrayList<String>> inviteList = new ArrayList<ArrayList<String>>();
emailAdapter = new ListViewAdapter(this,inviteList);
listView.setAdapter(emailAdapter);
// Assign adapter to ListView
listView.setTextFilterEnabled(true);
//Edit listeners
imgView_mail.setOnClickListener(new View.OnClickListener() {
public void onClick(View view)
{
//variables
final String enteredMail = "testListViewEntry";
final ArrayList<ArrayList<String>> inviteList = new ArrayList<ArrayList<String>>();
ArrayList<String> invite = new ArrayList<String>();
invite.add(0, enteredMail);//add first email
invite.add(1,"icon_invitestatussent.png"); //add first status icon
inviteList.add(invite);
emailAdapter.notifyDataSetChanged();
listView.setAdapter(emailAdapter);
}
});
}
}
Adapter class
public class ListViewAdapter extends BaseAdapter {
private Activity context;
ArrayList<ArrayList<String>> inviteDetails = new ArrayList<ArrayList<String>>();
public ListViewAdapter(Activity context, ArrayList<ArrayList<String>> inviteDetails ) {
this.inviteDetails = inviteDetails;
this.context = context;
}
#Override
public int getCount() {
return 0;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
public View getView(int position, View view, ViewGroup parent){
//Inflater
LayoutInflater inflater = context.getLayoutInflater();
//get row view
if (view == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
view = mInflater.inflate(R.layout.list_item_email, null);
}
//assign controls
final TextView textView_playerEmail = (TextView) view.findViewById(R.id.textView_playerEmail);
ImageView imgView_inviteStatus = (ImageView) view.findViewById(R.id.imgView_inviteStatus);
//Assign control values that are dynamic
textView_playerEmail.setText(inviteDetails.get(position).get(0));
imgView_inviteStatus.setImageResource(R.drawable.icon_invitestatussent);
return view;
}
public ArrayList<ArrayList<String>> addInvite(ArrayList<String> inviteDetails, ArrayList<ArrayList<String>> currentInvites)
{
currentInvites.add(inviteDetails);
return currentInvites;
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
}
Custom row xml
<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:id="#+id/textView_playerEmail"
android:textColor="#color/white"
android:text="item1">
</TextView>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imgView_inviteStatus" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imgView_remove"
android:src="#drawable/btn_cancel" />
Activity layout
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:weightSum="1"
android:gravity="left|center">
<ImageView
android:layout_width="45dp"
android:layout_height="34dp"
android:id="#+id/imgView_mail"
android:src="#drawable/btn_mail"
android:layout_weight="0.22"
android:padding="3dp" />
</LinearLayout>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listView_invitePlayers"
android:layout_gravity="center_horizontal" />
</LinearLayout>
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:id="#+id/btn_confirm"
android:src="#drawable/btn_confirm"
android:clickable="false"
android:adjustViewBounds="true"
android:layout_gravity="center_horizontal"
android:padding="2dp"
android:layout_weight="1" />
</LinearLayout>
From reading the description of the question I think you need to set custom adapter to show the elements in you listview. This is how you set the custom adapter for the listview:
public class Notes_list extends BaseAdapter
{
private Context mContext;
private ArrayList<String> id;
private ArrayList<String> firstName;
private ArrayList<String> lastName;
public Notes_list(Context c, ArrayList<String> id,ArrayList<String> fname, ArrayList<String> lname)
{
this.mContext = c;
this.id = id;
this.firstName = fname;
this.lastName = lname;
}
public int getCount() {
return id.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int pos, View child, ViewGroup arg2) {
Holder mHolder;
LayoutInflater layoutInflater;
if (child == null) {
layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
child = layoutInflater.inflate(R.layout.custom_row, null);
mHolder = new Holder();
// mHolder.txt_id = (TextView) child.findViewById(R.id.txt_id);
mHolder.txt_fName = (TextView) child.findViewById(R.id.txt_fName);
mHolder.txt_lName = (TextView) child.findViewById(R.id.txt_lName);
child.setTag(mHolder);
} else
{
mHolder = (Holder) child.getTag();
}
// mHolder.txt_id.setText(id.get(pos));
mHolder.txt_fName.setText(firstName.get(pos));
mHolder.txt_lName.setText(lastName.get(pos));
return child;
}
public class Holder
{
// TextView txt_id;
TextView txt_fName;
TextView txt_lName;
}
}
now in your main activity where you have to call the list enter code like this:
private ListView userList;
private ArrayList<Employee> itemsList = new ArrayList<modelName>();
userList = (ListView) findViewById(R.id.List);
UserList disadpt = new UserList(MainActivity.this, itemsList);
userList.setAdapter(disadpt);
Hope it helps...
I am new to android and i am working on listview. I am trying to show data using listview in xml and adapter in class file. I am working on following 3 files.
First file: activity_main.xml
<RelativeLayout 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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.listpractice.MainActivity" >
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:drawSelectorOnTop="false"
></ListView>
</RelativeLayout>
Second file: row1.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="?android:attr/listPreferredItemHeight" >
<ImageView
android:id="#+id/icon"
android:contentDescription="#string/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:src="#drawable/ic_launcher"
/>
<TextView
android:id="#+id/firstTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_toRightOf="#id/icon"
android:layout_toEndOf="#id/icon"
android:textSize="30sp"
android:text="#string/hello_world"
/>
<TextView
android:id="#+id/secondTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/icon"
android:layout_toEndOf="#id/icon"
android:layout_below="#id/firstTextView"
android:textSize="13sp"
android:text="#string/hello_world"
/>
</RelativeLayout>
Third file: MainActivity.java
package com.listpractice;
import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
public class MainActivity extends ListActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
My Problem : Now i want to show data of row1.xml but i don't have dynamic data. how can i show data using third(.class) file.
check out this link it will help http://androidexample.com/Create_A_Simple_Listview_-_Android_Example/index.php?view=article_discription&aid=65&aaid=90
either you need to create adapter file
public class CustomBaseAdapter extends BaseAdapter{
Context context;
List<RowItem> rowItems;
public CustomBaseAdapter(Context context, List<RowItem> items) {
this.context = context;
this.rowItems = items;
}
/*private view holder class*/
private class ViewHolder {
ImageView imageView;
TextView txtTitle;
//TextView txtDesc;
ImageView imgarrow;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, null);
holder = new ViewHolder();
//holder.txtDesc = (TextView) convertView.findViewById(R.id.desc);
holder.txtTitle = (TextView) convertView.findViewById(R.id.title);
holder.imageView = (ImageView) convertView.findViewById(R.id.icon);
holder.imgarrow=(ImageView)convertView.findViewById(R.id.arrow_icon);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
RowItem rowItem = (RowItem) getItem(position);
//holder.txtDesc.setText(rowItem.getDesc());
holder.txtTitle.setText(rowItem.getTitle());
holder.imageView.setImageResource(rowItem.getImageId());
holder.imgarrow.setImageResource(rowItem.getImg());
return convertView;
}
#Override
public int getCount() {
return rowItems.size();
}
#Override
public Object getItem(int position) {
return rowItems.get(position);
}
#Override
public long getItemId(int position) {
return rowItems.indexOf(getItem(position));
}
}
MainActivity
public class MainActivity extends Activity implements OnItemClickListener{
public static final String[] titles = new String[] { "Krish",
"John Cena", "Kane","Roman Reigns"};
public static final Integer[] images = { R.drawable.fourth,R.drawable.second,R.drawable.first,R.drawable.third};
public static final Integer[] imagearow = {R.drawable.arrow,R.drawable.arrow,R.drawable.arrow,R.drawable.arrow };
ListView listView;
List<RowItem> rowItems;
private ImageView btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.list_item_home);
//list_travels=(ListView)findViewById(R.id.list_travels);
btn=(ImageView)findViewById(R.id.btnaddhotels);
btn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0)
{
Intent i=new Intent(HomeScreen.this,Registerhotel_resorts.class);
startActivity(i);
}
});
rowItems = new ArrayList<RowItem>();
for (int i = 0; i < titles.length; i++) {
RowItem item = new RowItem(images[i], titles[i],imagearow[i]);
rowItems.add(item);
}
listView = (ListView) findViewById(R.id.list_hotels);
CustomBaseAdapter adapter = new CustomBaseAdapter(this, rowItems);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Toast toast = Toast.makeText(getApplicationContext(),
"Item " + (position + 1) + ": " + rowItems.get(position),
Toast.LENGTH_SHORT);
toast.setGravity(Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0);
toast.show();
Intent i1=new Intent(HomeScreen.this,KrishnaParkResort.class);
startActivity(i1);
}
}
You should read this article on Building Layouts with an Adapter. It has some handy concepts which you will need to get your head around.
The fundamental concept is that you need to link your ListView to an Adapter which populates the rows and adds them to the ListView.
Looking at your row1.xml, it looks like you will need a collection of objects which contain;
An image for icon
String for firstTextView
String for secondTextView
You can build a little snippet to create an array of prepopulated objects for test purposes.
public class YourObject {
private Bitmap icon;
private String text1;
private String text2;
public YourObject(Bitmap icon, String text1, String text2) {
this.icon = icon;
this.text1 = text1;
this.text2 = text2;
}
// GETTERS AND SETTERS
}
Then create a collection of them
List<YourObject> data = new ArrayList<>();
for (int z = 0; z < 5; z++) {
YourObject yourObject = new YourObject(yourIcon, "Text1: " + z, "Text2: " + z);
data.add(yourObject);
}
Once you have this collection, you send it to a your Adapter constructor along with the reference to row1.xml, then follow the guide to populate the rows.
I sample sensors (That's make the ListView busy) with custom user rate and I show the values in my listview, therefore I have a custom listview with 3 textview (for x, y and z values) and one spinner.
my layout is:
<?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="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:minWidth="140dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="X:"
android:id="#+id/tvX"
android:focusable="false"
android:focusableInTouchMode="false"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Y:"
android:focusable="false"
android:focusableInTouchMode="false"
android:id="#+id/tvY" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Z:"
android:focusable="false"
android:focusableInTouchMode="false"
android:id="#+id/tvZ" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="30dp">
<Spinner
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:id="#+id/spinner"/>
</LinearLayout>
</LinearLayout>
and I using this code as adapter:
public class customListView extends BaseAdapter
{
public Activity context;
ArrayList<MyActivity.SensorProperties> sensorPropertieses;
public String[] spinnerValues;
public LayoutInflater inflater;
public customListView(Activity context, ArrayList<MyActivity.SensorProperties> sensorPropertieses, String[] spinnerArray)
{
super();
this.context = context;
this.sensorPropertieses = sensorPropertieses;
spinnerValues = spinnerArray;
this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return sensorPropertieses.size();
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
class ViewHolder
{
TextView Xvalue, Yvalue, Zvalue;
Spinner spinner;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup)
{
ViewHolder holder;
if (view == null)
{
holder = new ViewHolder();
view = inflater.inflate(R.layout.custom_layout, null);
holder.Xvalue = (TextView) view.findViewById(R.id.tvX);
holder.Yvalue = (TextView) view.findViewById(R.id.tvY);
holder.Zvalue = (TextView) view.findViewById(R.id.tvZ);
holder.spinner = (Spinner) view.findViewById(R.id.spinner);
// populate spinner
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>
(view.getContext(), android.R.layout.simple_spinner_item, spinnerValues);
holder.spinner.setAdapter(dataAdapter);
view.setTag(holder);
}
else
holder = (ViewHolder) view.getTag();
// update sensor values
holder.Xvalue.setText(String.valueOf("X: " + sensorPropertieses.get(i).x));
holder.Yvalue.setText(String.valueOf("Y: " + sensorPropertieses.get(i).y));
holder.Zvalue.setText(String.valueOf("Z: " + sensorPropertieses.get(i).z));
return view;
}
}
my main activity code is (the layout contain only a button and listview):
public class MyActivity extends Activity implements SensorEventListener
{
public class SensorProperties
{
public float x = 0, y = 0, z = 0;
}
ListView listView;
ArrayList<SensorProperties> sensorPropertieses = new ArrayList<SensorProperties>();
customListView adapter;
SensorManager sensorManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
// let's work only on two nodes
sensorPropertieses.add(new SensorProperties());
sensorPropertieses.add(new SensorProperties());
listView = (ListView) findViewById(R.id.listView);
String[] spinnerValues = new String[] {"A", "B", "C"};
adapter = new customListView(MyActivity.this, sensorPropertieses, spinnerValues);
listView.setAdapter(adapter);
Button btnRegister = (Button) findViewById(R.id.buRegister);
btnRegister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view)
{
RegisterToSensors();
}
});
}
void RegisterToSensors()
{
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_GAME);
}
#Override
public void onSensorChanged(SensorEvent sensorEvent)
{
SensorProperties tmp = new SensorProperties();
tmp.x = sensorEvent.values[0];
tmp.y = sensorEvent.values[1];
tmp.z = sensorEvent.values[2];
if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
sensorPropertieses.set(0, tmp);
else
sensorPropertieses.set(1, tmp);
adapter.notifyDataSetChanged();
}
///...
}
The question: How should I work with ListView contains TextView and Spinner witout lost spinner focus although I update the TextView frequency?
EDIT:
I change question title and body thanks to mmlooloo comments.
To be clear:
I success to drop-down the spinner if the ListView isn't busy
I success to drop-down spinner when I updating TextView frequency not in ListView
The issue occur only with ListView and only when the listview is busy
EDIT2:
Currently, I'm not sure if the issue is the losing spinner focus or not. for debugging I add sleep of 30ms before I updating sensors value in the textviews (before // update sensor values) in my custom list view:
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
And I success to drop-down the spinner and choose another item while the textview updating (everything is very slow, but works!).
NEW: I have find, right now, probably the issue is with adapter.notifyDataSetChanged() because I cannot drop down the spinner also when I gray-out the textview prints
Bottom line, I'm not really know what is the root cause but I cannot drop-down the spinner when I update text views frequency in listview, and the question is why?
I'll be glad for any help, Thank you!
Issue here is you are frequently calling adapter.notifyDataSetChanged(); in your onSensorChanged method, so it binds listview every time so does
your getView is called every time and which sets spinner value every time.
What I did is, accessed your listview first and second child in onSensorChanged method and from that I have accessed texviews and update them as frequently as you want
and you can access your spinner too.
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
// SensorProperties tmp = new SensorProperties();
// tmp.x = sensorEvent.values[0];
// tmp.y = sensorEvent.values[1];
// tmp.z = sensorEvent.values[2];
// if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
// sensorPropertieses.set(0, tmp);
// else
// sensorPropertieses.set(1, tmp);
// adapter.notifyDataSetChanged();
Log.i("tag", "ensorEvent.values[0] = " + sensorEvent.values[0]);
if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
View childView = (View) listView.getChildAt(0);
TextView xTextView = (TextView) childView.findViewById(R.id.tvX);
xTextView.setText(String.valueOf(sensorEvent.values[0]));
TextView yTextView = (TextView) childView.findViewById(R.id.tvY);
yTextView.setText(String.valueOf(sensorEvent.values[1]));
TextView zTextView = (TextView) childView.findViewById(R.id.tvZ);
zTextView.setText(String.valueOf(sensorEvent.values[2]));
} else {
View childView = (View) listView.getChildAt(1);
TextView xTextView = (TextView) childView.findViewById(R.id.tvX);
xTextView.setText(String.valueOf(sensorEvent.values[0]));
TextView yTextView = (TextView) childView.findViewById(R.id.tvY);
yTextView.setText(String.valueOf(sensorEvent.values[1]));
TextView zTextView = (TextView) childView.findViewById(R.id.tvZ);
zTextView.setText(String.valueOf(sensorEvent.values[2]));
}
}
Run this code it gives you some idea!!
public class MainActivity extends ActionBarActivity {
List<myItem> myItemList;
ListView list;
boolean isTouchEvent = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myItemList = new ArrayList<myItem>();
for (int i = 0; i < 9; i++) {
myItem m = new myItem();
m.setMyText("This is item number "+i);
myItemList.add(m);
}
list = (ListView)findViewById(R.id.list);
list.setAdapter(new MyAdapter(this, R.layout.list_item, myItemList));
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Toast.makeText(MainActivity.this, "You have clicked item number "+arg2, Toast.LENGTH_SHORT).show();
}
});
list.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
isTouchEvent = true;
return false;
}
});
}
class MyAdapter extends ArrayAdapter<myItem> {
Context ctx;
public MyAdapter(Context context, int resource, List<myItem> objects) {
super(context, resource, objects);
ctx = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView == null){
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater)ctx.getSystemService (Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_item, parent, false);
holder.txt = (TextView)convertView.findViewById(R.id.TextView_txt);
holder.sp = (Spinner)convertView.findViewById(R.id.Spinner_sp);
List<String> spinnerValues = new ArrayList<String>();
for (int i = 0; i < 5; i++) {
String temp = "Val #" + i;
spinnerValues.add(temp);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(ctx,android.R.layout.simple_spinner_item,spinnerValues);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
holder.sp.setAdapter(adapter);
convertView.setTag(holder);
}else {
holder = (ViewHolder)convertView.getTag();
}
holder.sp.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
isTouchEvent = true;
return false;
}
});
holder.sp.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
if(!isTouchEvent){
return;
}
String spinnerStringValue = (String)holder.sp.getAdapter().getItem(arg2);
holder.txt.setText("You have selected "+ spinnerStringValue );
holder.txt.invalidate();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
holder.txt.setText(myItemList.get(position).getMyText());
return convertView;
}
}
static class ViewHolder {
public TextView txt;
public Button bt;
public Spinner sp;
}
public class myItem {
private String myText="";
public String getMyText() {
return myText;
}
public void setMyText(String myText) {
this.myText = myText;
}
}
}
activity_main.xml:
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
/>
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
android:orientation="horizontal" >
<TextView
android:id="#+id/TextView_txt"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="16dip" />
<Spinner
android:id="#+id/Spinner_sp"
android:layout_marginLeft="50dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
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.