I have a listView with n number of rows each row contains textview1(for text), textview2(For id) and spinner. I want to select spinner in multiple rows. Here the problem is once i scroll the listView the selection is gone (Recycle listView).
I have store the id in a ArrayList(Which rows spinner selected) and selected position of the spinner. In onScroll method of listView i try to use spinner.setSelection(position); but it won't work.
My sample image
And my source code:
level2.setOnScrollListener(new OnScrollListener() {
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
}
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
for (int i = 0; i < level2.getChildCount(); i++) {
RelativeLayout relative_layout = (RelativeLayout)level2.getChildAt(i);
TextView textview_1 = (TextView)relative_layout.getChildAt(0);
TextView textview_2 = (TextView)relative_layout.getChildAt(1);
Spinner spinner = (Spinner)relative_layout.getChildAt(2);
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView < ? > arg0,
View arg1, int arg2, long arg3) {
//save my id and spinner selection here in a ArrayList
//Here the position is get value from arraylist
spinner.setSelection(position);
}
public void onNothingSelected(AdapterView < ? > arg0) {
// TODO Auto-generated method stub
}
});
}
}
});
It is not complete code it's just piece. Please help me.
Here if u want to set the selected item then you have to use code spinner.setSelection(arg2);, As you have not initialised your position variable and its default value will be 0 , so it would always show the 1st item selected.
I'll solve like this.Try this. This is just example Activity.
public class MainActivity extends Activity {
SpinnerAdapter ratingAdapter;
ListView listView;
List<String> listString;
ArrayAdapter<String> dataAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listString = new ArrayList<String>();
for(int listCount = 0; listCount < 20 ; listCount++){
listString.add("ListCount"+listCount);
}
List<String> spinnerData = new ArrayList<String>();
for (int i = 0; i < listString.size(); i++) {
spinnerData.add("MyTest="+i);
}
dataAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1, spinnerData);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
fillAdapter();
}
private void fillAdapter() {
ratingAdapter = new SpinnerAdapter(getApplicationContext());
listView = (ListView) findViewById(R.id.listView1);
listView.setAdapter(ratingAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
class ViewHolder {
Spinner spinner;
}
class SpinnerAdapter extends ArrayAdapter {
Context context;
HashMap<Integer,Integer> selectedItems = new HashMap<Integer, Integer>();
public SpinnerAdapter(Context context) {
super(context, R.layout.item_list_spinner_adaoter, listString);
this.context = context;
}
public int getCount() {
return listString.size();
}
public Object getItem(int position) {
return listString.get(position);
}
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.item_list_spinner_adaoter, null);
holder.spinner = (Spinner) convertView.findViewById(R.id.spinner1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.spinner.setAdapter(dataAdapter);
if ( selectedItems.get( position ) != null ) {
holder.spinner.setSelection( selectedItems.get( position ) );
}
holder.spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
selectedItems.put( position, arg2 );
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
return convertView;
}
}
}
In activity_main.xml:
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:stackFromBottom="false"
android:transcriptMode="disabled" >
</ListView>
</LinearLayout>
In item_list_spinner_adaoter.xml:
<Spinner
android:id="#+id/spinner1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Related
I have a custom list view, contains delete button and spinner (the spinner contain A-E characters).
And I have an issue with deleting the true row from my custom list view.
Custom list view code:
public class customListView extends BaseAdapter
{
public Activity context;
ArrayList<MyActivity.UserProperties> userPropertieses;
public String[] spinnerValues;
public LayoutInflater inflater;
public customListView(Activity context, ArrayList<MyActivity.UserProperties> userPropertieses, String[] spinnerArray)
{
super();
this.context = context;
this.userPropertieses = userPropertieses;
spinnerValues = spinnerArray;
this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() { return userPropertieses.size(); }
#Override
public Object getItem(int i) { return null; }
#Override
public long getItemId(int i) { return 0; }
class ViewHolder
{
Button btnRemove;
Spinner spinner;
}
#Override
public View getView(final int i, View view, ViewGroup viewGroup)
{
final ViewHolder holder;
if (view == null)
{
holder = new ViewHolder();
view = inflater.inflate(R.layout.custom_layout, null);
holder.spinner = (Spinner) view.findViewById(R.id.spinner);
holder.btnRemove = (Button) view.findViewById(R.id.bu_Remove);
// populate spinner
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>
(view.getContext(), android.R.layout.simple_spinner_item, spinnerValues);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
holder.spinner.setFocusable(true);
holder.spinner.requestFocus();
holder.spinner.setAdapter(dataAdapter);
view.setTag(holder);
// remove user implementation
holder.btnRemove.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.i("custom list view debug", "i = " + i); // debug. verify i value is correct
((MyActivity) context).deleteUser(i);
}
});
}
else
holder = (ViewHolder) view.getTag();
return view;
}
}
And my main activity code looks like this:
public class MyActivity extends Activity
{
ListView listView;
ArrayList<UserProperties> userProperties = new ArrayList<UserProperties>();
customListView adapter;
SensorManager sensorManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
for (int i = 0; i<5; i++) {
userProperties.add(new UserProperties());
}
listView = (ListView) findViewById(R.id.listView);
String[] spinnerValues = new String[] {"A", "B", "C", "D", "E"};
adapter = new customListView(MyActivity.this, userProperties, spinnerValues);
listView.setAdapter(adapter);
}
public void deleteUser (int index)
{
Log.i("debug", "Removing item " + index); // the index is really true and the true node deleting from the ArrayList but somehow the latest delete from the UI
userProperties.remove(index);
adapter.notifyDataSetChanged();
}
}
When I click on the Remove button deleteUser method called with the right index. but although the right node deleting from userProperties ArrayList somehow after notiftDataSetChanged is still alive
and the latest node delete.
So, How can I delete the right node/row (from the ArrayList and UI...)
Thank you!
EDIT:
Just to be clear, i variable contain true index. The true node deleted from the ArrayList. but something append after I called notify method.
I prefer to stay with BaseAdapter and not implement ArrayAdapter. Thank you!
EDIT 2:
After more debugging I found out my question was wrong. the true row really deleted just spinner values somehow update their values. I cannot close the question because it already answered. Thanks.
((MyActivity) context).deleteUser(i);
This line will always delete the first value from the ListView
You can use CAB (contextual action bar)
See if the code helps you(it's basically a ListActivity with a custom adapter to hold the status of checked items(+ different background)):
public class CABSelection extends ListActivity {
private ArrayList<String> mItems = new ArrayList<String>();
private SelectionAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
for (int i = 0; i < 24; i++) {
mItems.add("Name" + i);
}
// R.layout.adapters_cabselection_row is a LinearLayout(with green
// background(#99cc00)) that wraps an ImageView and a TextView
mAdapter = new SelectionAdapter(this,
R.layout.adapters_cabselection_row, R.id.the_text, mItems);
setListAdapter(mAdapter);
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
getListView().setMultiChoiceModeListener(new MultiChoiceModeListener() {
private int nr = 0;
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.cabselection_menu, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
StringBuilder sb = new StringBuilder();
Set<Integer> positions = mAdapter.getCurrentCheckedPosition();
for (Integer pos : positions) {
sb.append(" " + pos + ",");
}
switch (item.getItemId()) {
case R.id.edit_entry:
Toast.makeText(CABSelection.this, "Edited entries: " + sb.toString(),
Toast.LENGTH_SHORT).show();
break;
case R.id.delete_entry:
Toast.makeText(CABSelection.this, "Deleted entries : " + sb.toString(),
Toast.LENGTH_SHORT).show();
break;
case R.id.finish_it:
nr = 0;
mAdapter.clearSelection();
Toast.makeText(CABSelection.this, "Finish the CAB!",
Toast.LENGTH_SHORT).show();
mode.finish();
}
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
nr = 0;
mAdapter.clearSelection();
}
#Override
public void onItemCheckedStateChanged(ActionMode mode,
int position, long id, boolean checked) {
if (checked) {
nr++;
mAdapter.setNewSelection(position, checked);
} else {
nr--;
mAdapter.removeSelection(position);
}
mode.setTitle(nr + " rows selected!");
}
});
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
l.setItemChecked(position, !mAdapter.isPositionChecked(position));
}
private class SelectionAdapter extends ArrayAdapter<String> {
private HashMap<Integer, Boolean> mSelection = new HashMap<Integer, Boolean>();
public SelectionAdapter(Context context, int resource,
int textViewResourceId, List<String> objects) {
super(context, resource, textViewResourceId, objects);
}
public void setNewSelection(int position, boolean value) {
mSelection.put(position, value);
notifyDataSetChanged();
}
public boolean isPositionChecked(int position) {
Boolean result = mSelection.get(position);
return result == null ? false : result;
}
public Set<Integer> getCurrentCheckedPosition() {
return mSelection.keySet();
}
public void removeSelection(int position) {
mSelection.remove(position);
notifyDataSetChanged();
}
public void clearSelection() {
mSelection = new HashMap<Integer, Boolean>();
notifyDataSetChanged();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);//let the adapter handle setting up the row views
v.setBackgroundColor(Color.parseColor("#99cc00")); //default color
if (mSelection.get(position) != null) {
v.setBackgroundColor(Color.RED);// this is a selected position so make it red
}
return v;
}
}
}
Another way
adapter = new MyListAdapter(this);
lv = (ListView) findViewById(android.R.id.list);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
AlertDialog.Builder adb=new AlertDialog.Builder(MyActivity.this);
adb.setTitle("Delete?");
adb.setMessage("Are you sure you want to delete " + position);
final int positionToRemove = position;
adb.setNegativeButton("Cancel", null);
adb.setPositiveButton("Ok", new AlertDialog.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
MyDataObject.remove(positionToRemove);
adapter.notifyDataSetChanged();
}});
adb.show();
}
});
getView(final int i,
Do not make i final. You did that to use i in onClick(). But that is not possible. So remove the final. Add:
holder.btnRemove.setTag(i);
And in onClick:
int position = v.getTag();
..deleteUser(position);
Maybe you have to cast something somewhere..
Remark: You have to set the tag always. So do it just before return view;.
Please do not use an i for position.
I have a list view. Each list view contain spinner and I want to get the value of each spinner. But it doesn't work. It is ok if the listview is not scroll able.
private void checkPrice(){
float total = 0;
Log.d(TAG,"This is qty: "+ quantity);
for (int i=0; i < mProductItems.size(); i++){
View view = mListView.getChildAt(i);
float eachTotal = 0;
float discountAmount = 0;
// Get Quantity
Spinner getQtyView = (Spinner) view.findViewById(R.id.spQty);
String getQty = getQtyView.getSelectedItem().toString();
Integer qty = Integer.parseInt(getQty);
// Get Line item amount view
TextView txvAmount = (TextView) view.findViewById(R.id.txvAmount);
// Get product by view position
OEDataRow eachProduct = (OEDataRow) mProductItems.get(i);
Integer eachPrice = eachProduct.getInt("retail_price");
// Check Discount
if (eachProduct.getBoolean("promotion_disc")){
float promo = (float) eachProduct.getInt("promotion_amount")/100;
Log.d(TAG,"this is promo: "+promo);
discountAmount = (float)( eachPrice * qty ) * promo;
}else {
discountAmount = 0;
}
eachTotal = (float)( eachPrice * qty ) - discountAmount;
txvAmount.setText(String.format("%.2f", eachTotal));
Log.d(TAG, "Each Total: " + eachTotal);
total = eachTotal + total;
Log.d(TAG,"Total: "+ total);
}
btnCheckout.setText("Checkout: "+String.format("%.2f", total));
}
Thanks for your time.
I've the same problem. I'll solve like this.Try this. This is just example Activity.
public class MainActivity extends Activity {
SpinnerAdapter ratingAdapter;
ListView listView;
List<String> listString;
ArrayAdapter<String> dataAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listString = new ArrayList<String>();
for(int listCount = 0; listCount < 20 ; listCount++){
listString.add("ListCount"+listCount);
}
List<String> spinnerData = new ArrayList<String>();
for (int i = 0; i < listString.size(); i++) {
spinnerData.add("MyTest="+i);
}
dataAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1, spinnerData);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
fillAdapter();
}
private void fillAdapter() {
ratingAdapter = new SpinnerAdapter(getApplicationContext());
listView = (ListView) findViewById(R.id.listView1);
listView.setAdapter(ratingAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
class ViewHolder {
Spinner spinner;
}
class SpinnerAdapter extends ArrayAdapter {
Context context;
HashMap<Integer,Integer> selectedItems = new HashMap<Integer, Integer>();
public SpinnerAdapter(Context context) {
super(context, R.layout.item_list_spinner_adaoter, listString);
this.context = context;
}
public int getCount() {
return listString.size();
}
public Object getItem(int position) {
return listString.get(position);
}
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.item_list_spinner_adaoter, null);
holder.spinner = (Spinner) convertView.findViewById(R.id.spinner1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.spinner.setAdapter(dataAdapter);
if ( selectedItems.get( position ) != null ) {
holder.spinner.setSelection( selectedItems.get( position ) );
}
holder.spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
selectedItems.put( position, arg2 );
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
return convertView;
}
}
}
In activity_main.xml:
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:stackFromBottom="false"
android:transcriptMode="disabled" >
</ListView>
</LinearLayout>
In item_list_spinner_adaoter.xml:
<Spinner
android:id="#+id/spinner1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
I have a listview of that have multiple items.I want to update the items value on click of button and want to get the the values of all the items on click of the button.But i am unable to do that.Please help me to get this functionality
Activity code
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_ItemValue);
setContentView(R.layout.activity_iween_booking_page);
listView = (ListView) findViewById(R.id.passengerList);
showPassengerListView(passengerList);
}
getValue.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
if(){
}else{
//Here i have to get all the value of the listview items in a array
}
}
});
}
private void showPassengerListView(final String[] passengerList) {
listView.setAdapter(new PassengerListUpdate(passengerList));
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
}
});
}
public void passengerInformationPopup(final String[] passengerList, final int position) {
final Dialog dialog= new Dialog(MainActivity.this,R.style.Dialog_Fullscreen);
dialog.setContentView(R.layout.passenger_details_dialog);
dialog.show();
setValueDialog.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
isSuccess= true;
if(isSuccess){
dialog.cancel();
//Here i Have to Update the item at position with some value
}
}
});
}
public void goBack(View v) {
finish();
}
class PassengerListUpdate extends BaseAdapter {
String[] ItemValue;
public PassengerListUpdate(String[] text) {
ItemValue = text;
}
public int getCount() {
// TODO Auto-generated method stub
return ItemValue.length;
}
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View vi;
vi = inflater.inflate(android.R.layout.simple_list_item_1, parent, false);
TextView ItemValue;
ItemValue = (TextView) vi.findViewById(android.R.id.text1);
ItemValue.setText(ItemValue[position]);
return (vi);
}
}
Please help me to how to set a items value and how to get the listview values
[Want] to get the the values of all the items on click of the button
To get all values, create a method getAllValues() inside PassengerListUpdate:
public String[] getAllValues() {
return ItemValue;
}
Declare your adapter globally:
PassengerListUpdate myAdapter;
Initialize it in showPassengerListView(String[]):
myAdapter = new PassengerListUpdate(passengerList);
listView.setAdapter(myAdapter);
To get the list of all values on button click:
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (myAdapter != null) {
String[] allValues = myAdapter.getAllValues();
}
}
});
I want to update the items value on click of button
To update the values, you can simply reinitialize and set myAdapter:
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
myAdapter = new PassengerListUpdate(updatedPassengerList);
listView.setAdapter(myAdapter);
}
});
First, in order to get whole the values inside ListView. You can get number of item in adapter, and then get value one by one by its position.
ArrayList<String> results = new ArrayList<String>();
final int count = mMyAdapter.getCount();
for( int i = 0; i < count; ++i ){
String item = mMyAdapter.getItem(i);
results.add(item);
}
return results;
Second, in order to add or update the value of ListView, in general extending ArrayAdapter is much easier than implementing BaseAdapter, because of ArrayAdapter support add / remove / insert method by itself. For example,
public class MyAdapter extends ArrayAdapter<String> {
public MyAdapter(Context context) {
super(context, 0);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View vi;
vi = inflater.inflate(android.R.layout.simple_list_item_1, parent, false);
TextView ItemValue;
ItemValue = (TextView) vi.findViewById(android.R.id.text1);
ItemValue.setText(ItemValue[position]);
return (vi);
}
}
And you can updating adapter's value quiet directly,
mMyAdapter.add("Add Item");
mMyAdapter.remove("Remove Item");
mMyAdapter.insert("Insert Item", 0);
After finishing the jobs, you can call adapter's notifyDatSetChanged() method in order to update the UI, and I think this is more efficient way than setting up the new adapter every time whenever data is updated.
mMyAdapter.notifyDataSetChanged();
I have a listview that has a custom adapter, and I was trying to make it searchable using an Action Item. When I click the search icon in the action bar, the edit text comes up, but when I enter text and click "done" on the keyboard, nothing happens.
Here is the main class:
public class ItemId extends SherlockListActivity {
EditText editsearch;
ArrayAdapter<String> adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context ctx = getApplication();
Resources res = ctx.getResources();
String[] options = res.getStringArray(R.array.item_ids);
String[] ids = res.getStringArray(R.array.item_names);
TypedArray icons = res.obtainTypedArray(R.array.item_images);
adapter = new ItemIDAdapter(ctx, R.layout.idslistitem, ids, options, icons);
setListAdapter(adapter );
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Get the options menu view from menu.xml in menu folder
getSupportMenuInflater().inflate(R.menu.items_menu, menu);
// Locate the EditText in menu.xml
editsearch = (EditText) menu.findItem(R.id.menu_search).getActionView();
// Capture Text in EditText
editsearch.addTextChangedListener(textWatcher);
// Show the search menu item in menu.xml
MenuItem menuSearch = menu.findItem(R.id.menu_search);
menuSearch.setOnActionExpandListener(new OnActionExpandListener() {
// Menu Action Collapse
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
// Empty EditText to remove text filtering
editsearch.setText("");
editsearch.clearFocus();
return true;
}
// Menu Action Expand
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
// Focus on EditText
editsearch.requestFocus();
// Force the keyboard to show on EditText focus
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
return true;
}
});
// Show the settings menu item in menu.xml
MenuItem menuSettings = menu.findItem(R.id.home);
// Capture menu item clicks
menuSettings.setOnMenuItemClickListener(new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
Intent intent2 = new Intent(ItemId.this, Home.class);
startActivity(intent2);
return true;
}
});
return true;
}
// EditText TextWatcher
private TextWatcher textWatcher = new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
String text = editsearch.getText().toString()
.toLowerCase(Locale.getDefault());
adapter.getFilter().filter(text);
};
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
};
}
And here is the Adapter class:
public class ItemIDAdapter extends ArrayAdapter<String> implements Filterable {
public LayoutInflater mInflater;
public String[] mStrings;
public String[] mIds;
public TypedArray mIcons;
public int mViewResourceId;
public ItemIDAdapter(Context ctx, int viewResourceId,
String[] strings, String[] ids, TypedArray icons) {
super(ctx, viewResourceId, strings);
mInflater = (LayoutInflater)ctx.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
mStrings = strings;
mIds = ids;
mIcons = icons;
mViewResourceId = viewResourceId;
}
#Override
public int getCount() {
return mStrings.length;
}
#Override
public String getItem(int position) {
return mStrings[position];
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = mInflater.inflate(mViewResourceId, null);
ImageView iv = (ImageView)convertView.findViewById(R.id.option_icon);
iv.setImageDrawable(mIcons.getDrawable(position));
TextView tv = (TextView)convertView.findViewById(R.id.option_text);
tv.setText(mStrings[position]);
TextView tv1 = (TextView)convertView.findViewById(R.id.itemids);
tv1.setText(mIds[position]);
return convertView;
}
}
If anyone has any idea as to why nothing happens when I search, or knows how to fix it, it'd be greatly appreciated. Thanks!!
You need to implement a custom filter. Have a look at this post here someone else has had a similar problem which he solved: https://stackoverflow.com/a/8258457/2045570
Below is mine code, which is working perfectly:-
public class ExpenditureAdapter extends ArrayAdapter<Expenditure> implements Filterable {
ArrayList<Expenditure> listArray;
ArrayList<Expenditure> filteredlistArray;
private Filter mFilter;
public ExpenditureAdapter(#NonNull Context context, ArrayList<Expenditure> list) {
super(context,0, list);
listArray=list;
filteredlistArray=list;
}
#Override
public int getCount() {
return filteredlistArray.size(); // total number of elements in the list
}
public void add(Expenditure object) {
listArray.add(object);
this.notifyDataSetChanged();
}
public Filter getFilter() {
if (mFilter == null) {
mFilter = new CustomFilter();
}
return mFilter;
}
#Override
public Expenditure getItem(int i) {
return filteredlistArray.get(i); // single item in the list
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
#Override
public long getItemId(int i) {
return i; // index number
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Expenditure expenditure = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.listexpenditure, parent, false);
}
// Lookup view for data population
TextView ExpId = (TextView) convertView.findViewById(R.id.ExpId);
TextView ExDate = (TextView) convertView.findViewById(R.id.ExDate);
TextView ExpAmt = (TextView) convertView.findViewById(R.id.ExpAmt);
TextView ExpDetail = (TextView) convertView.findViewById(R.id.ExpDetail);
// Populate the data into the template view using the data object
ExpId.setText(expenditure.ExpId);
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
String dateTime = dateFormat.format(expenditure.ExpDate);
ExDate.setText(dateTime);
ExpAmt.setText(String.valueOf(expenditure.ExpAmt));
ExpDetail.setText(expenditure.ExpDetail);
return convertView;
}
private class CustomFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if(constraint == null || constraint.length() == 0) {
ArrayList<Expenditure> list = new ArrayList<Expenditure>(listArray);
results.values = list;
results.count = list.size();
} else {
ArrayList<Expenditure> newValues = new ArrayList<Expenditure>();
for(int i = 0; i < listArray.size(); i++) {
Expenditure e_item = listArray.get(i);
if(e_item.ExpDetail.contains(constraint)) {
newValues.add(e_item);
}
}
results.values = newValues;
results.count = newValues.size();
}
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
filteredlistArray = (ArrayList<Expenditure>) results.values;
notifyDataSetChanged();
}
}
and use it in your code as below:-
private TextWatcher textWatcher = new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
String text = txtSearch.getText().toString()
.toLowerCase(Locale.getDefault());
adapter.getFilter().filter(text);
};
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
};
I have a Spinner on my Activity. I use an ArrayList and a custom SpinnerAdapter to populate the list that pops up when the Spinner is pressed.
My problem is the way the Spinner looks on the Activity when it is not pressed. It is all gray. No text is visible. Even after I press the spinner and then choose an item from the resulting list, the Spinner does not populate with text.
Also, when I select an item from the Spinner and then print the selected item position, it prints -1. Many have commented that there is no list of data attached to my spinner, but there obviously is. How else could I press on the Spinner and then choose from a resulting list?
// This sets up the adapter and the arraylist that contains the data
private void setUpAdapter() {
mData = new ArrayList<MyData>();
mAdapter = new MyAdapter(mData);
mSpinner.setAdapter(mAdapter);
mSpinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
MyData g = (MyData) parent.getItemAtPosition(pos);
// TODO
}
public void onNothingSelected(AdapterView parent) {
// Do nothing.
}
});
}
// this populates the arraylist that is attached to the spinner's adapter
// it is called once an AsyncTask finishes pulling data from a local database
private void populateSpinner(ArrayList<MyData> result) {
if (result != null) {
if (mData == null) {
mData = new ArrayList<MyData>();
}
else {
mData.clear();
}
for (int index = 0; index < result.size(); index++) {
mData.add(result.get(index));
}
mSpinner.setSelected(0);
}
}
// this is the adapter for the spinner
private class MyAdapter implements SpinnerAdapter {
ArrayList<MyData> data;
public MyAdapter(ArrayList<MyData> data){
this.data = data;
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return android.R.layout.simple_spinner_dropdown_item;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView v = new TextView(getApplicationContext());
v.setTextColor(Color.BLACK);
v.setText(data.get(position).getName());
v.setPadding(0, 20, 0, 20);
return v;
}
#Override
public int getViewTypeCount() {
return 1;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isEmpty() {
return false;
}
#Override
public void registerDataSetObserver(DataSetObserver observer) {
// TODO Auto-generated method stub
}
#Override
public void unregisterDataSetObserver(DataSetObserver observer) {
// TODO Auto-generated method stub
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return this.getView(position, convertView, parent);
}
}
<Spinner
android:id="#+id/my_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
When I select an item from the Spinner and then print the selected item position, it prints -1
This is because you are referencing BLANK list
mData = new ArrayList<MyData>();
mAdapter = new MyAdapter(mData);
mSpinner.setAdapter(mAdapter);
Set spinner adapter in onPostExecute() of AsynTask.
#Override
protected void onPreExecute() {
mData = new ArrayList<MyData>();
super.onPreExecute();
}
#Override
protected Void doInBackground(String... params) {
//gets "result" to fill mData
return null;
}
#Override
protected void onPostExecute(Void result) {
setUpAdapter();
}
private void setUpAdapter() {
if (result != null) {
if (mData == null) {
mData = new ArrayList<MyData>();
}
else {
mData.clear();
}
for (int index = 0; index < result.size(); index++) {
mData.add(result.get(index));
}
mAdapter = new MyAdapter(mData);
mSpinner.setAdapter(mAdapter);
mSpinner.setSelected(0);
mSpinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
MyData g = (MyData) parent.getItemAtPosition(pos);
// TODO
}
public void onNothingSelected(AdapterView parent) {
// Do nothing.
}
});
}
Use Activity context instead of the Application context for your spinner. See documentation of getApplicationContext() api to understand its proper usage.
Pass the activity context to MyAdapter and use it in creating the TextView's in getView callback.
mAdapter = new MyAdapter(mData, this); // this is activity context.
In MyAdapter :
public MyAdapter(ArrayList<MyData> data, Context context){
this.data = data;
mContext = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView v = new TextView(mContext);
v.setTextColor(Color.BLACK);
v.setBackgroundColor(Color.WHITE);
v.setText(data.get(position).getName());
v.setPadding(0, 20, 0, 20);
return v;
}
You can set static sizes using the xml attribute android:layout_height.
Using dp unit instead of px is recommended for multiple screen compatibility.
As for the text, try to use android:prompt attribute in your Spinner xml. For the color I'm guessing it's like other widgets, just use android:textColor
THIS code is WORKING, the spinner correctly display the field, however i must say maybe it is not 100% perfect, cause for some reason im unable to leave blank the initial value of the field, it has by default the value of item 0.
package com.cccheck;
public class OneCheckActivity extends Activity {
LayoutInflater factory;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.spinner_view);
ArrayList tdata = new ArrayList<MyData>();
MyData mdata =new MyData();
mdata.setName("");
mdata.setData("-1");
MyData ndata =new MyData();
ndata.setName("ciao belluzzo");
ndata.setData("1");
tdata.add(mdata);
tdata.add(ndata);
mdata= new MyData();
mdata.setName("vai alla fnac");
mdata.setData("2");
tdata.add(mdata);
mSpinner = (Spinner) findViewById(R.id.my_spinner);
factory = LayoutInflater.from(this);
populateSpinner(tdata);
setUpAdapter();
mSpinner.setSelected(false);
try {
mAdapter.notify();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//mAdapter.registerDataSetObserver(new MyObserver());
}
ArrayList<MyData> mData;
MyAdapter mAdapter = new MyAdapter(null);
Spinner mSpinner;
// This sets up the adapter and the arraylist that contains the data
private void setUpAdapter() {
mSpinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
MyData g = (MyData) parent.getItemAtPosition(pos);
// TODO
Toast.makeText(OneCheckActivity.this , "selected item : " + pos + ", value: " + g.getData(),Toast.LENGTH_LONG).show();
}
#Override
public void onNothingSelected(AdapterView parent) {
// Do nothing.
}
});
}
// this populates the arraylist that is attached to the spinner's adapter
//it is called once an AsyncTask finishes pulling data from a local database
private void populateSpinner(ArrayList<MyData> result) {
if (result != null) {
if (mData == null) {
mData = new ArrayList<MyData>();
}
else {
mData.clear();
}
for (int index = 0; index < result.size(); index++) {
mData.add(result.get(index));
}
mAdapter = new MyAdapter(mData);
mSpinner.setAdapter(mAdapter);
}
}
// this is the adapter for the spinner
private class MyAdapter implements SpinnerAdapter {
ArrayList<MyData> data;
public MyAdapter(ArrayList<MyData> data){
this.data = data;
}
public void updateData(ArrayList<MyData> data){
this.data = data;
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return android.R.layout.simple_spinner_dropdown_item;
}
#Override
public LinearLayout getView(int position, View convertView, ViewGroup parent) {
LinearLayout pv = (LinearLayout)(factory.inflate(R.layout.spinner_item, null));
TextView tv = (TextView) pv.findViewById(R.id.textviewid);
tv.setTextColor(Color.BLACK);
MyData item = data.get(position);
tv.setText( item.getName() + " - " + item.getData() + " ");
tv.setPadding(0, 20, 0, 20);
return pv;
}
#Override
public int getViewTypeCount() {
return 1;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isEmpty() {
return data.isEmpty();
}
#Override
public void registerDataSetObserver(DataSetObserver observer) {
// TODO Auto-generated method stub
}
#Override
public void unregisterDataSetObserver(DataSetObserver observer) {
// TODO Auto-generated method stub
}
#Override
public LinearLayout getDropDownView(int position, View convertView, ViewGroup parent) {
if (convertView instanceof LinearLayout) System.out.println("%%%%%%%%%%%%%%55555 hai ragione");
return this.getView(position, convertView, parent);
}
}
}
use this as layout for spinner_item.xml
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="28px"
android:id="#+id/textviewid"
/>
</LinearLayout>