listview checkbox trouble in android - android

i have a trouble with listview. i added a checkbox into listview to choose items. my data is coming from sqlite so i use simple cursor adapter. length of my list is aproximatley 250 lines. i am clicking a check box.when i scroll down page (list), checkbox is clicked in every 10 lines.(for example in my screen show 10 lines data when i scroll 11th lines, this row's checkbox had clicked. how can i solve this problem.
<?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"
android:orientation="vertical" >
<CheckBox
android:id="#+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
/>
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/checkBox"
android:textStyle="bold"
android:text="TextView" />
<TextView
android:id="#+id/nick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/nick"
android:layout_alignBottom="#+id/nick"
android:layout_alignParentRight="true"
android:text="TextView" />
<TextView
android:id="#+id/phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/name"
android:layout_toRightOf="#+id/checkBox"
android:text="TextView" />
</RelativeLayout>
and this is source code
package com.example.myprojects;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.widget.SimpleCursorAdapter;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import android.widget.ListView;
public class send_message extends Activity {
private ListView list;
private EditText search;
SimpleCursorAdapter adapterx;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sendmessage);
list=(ListView)findViewById(R.id.list);
search=(EditText)findViewById(R.id.search);
loadfromdatabase();
}
private void loadfromdatabase() {
mydb info=new mydb(this);
info.open_read();
Cursor c = info.getAllData();
String[] columns = new String[] {mydb.KEY_NAME,mydb.KEY_PHONE, mydb.KEY_NICK};
int[] to = new int[] {R.id.name,R.id.phone, R.id.nick };
#SuppressWarnings("deprecation")
SimpleCursorAdapter adapter= new SimpleCursorAdapter(this, R.layout.activity_sendmesage_rows, c, columns, to,0);
list.setAdapter(adapter);
info.close();
}
}

If you have CheckBoxes in ListView you have problem, because ListView reuses Views that aren't already visible on screen. That's why when you scroll down, it loads (a few times) that one CheckBox that was checked by you previously. So you can't rely on default CheckBox's behaviour. What you need is:
Prevent user from checking CheckBox. You can do this by calling cb.setEnabled(false), where cb is CheckBox which you are using.
Create your own adapter class that will extend SimpleCursorAdapter. In this class you will store list of indexes of items that are checked.
Override getView() method in your adapter class and there manually set CheckBox to be checked if it's position is stored in checked items array.
Create OnClickListener for your ListView which will take care of adding/removing checked items' positions from adapter's internal array.
Edit:
This would be the code of your adapter:
public class MySimpleCursorAdapter extends SimpleCursorAdapter {
public ArrayList<Integer> mItemsChecked;
public MySimpleCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
mItemsChecked = new ArrayList<Integer>();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
for(int i = 0; i < mItemsChecked.size(); i++) {
if(mItemsChecked.get(i) == position) {
CheckBox cb = (CheckBox)convertView.findViewById(R.id.checkBox1); // Instead of checkBox1, write your name of CheckBox
cb.setChecked(true);
}
}
return super.getView(position, convertView, parent);
}
/* Just a handy method that will be responsible for adding/removing
items' positions from mItemsChecked list */
public void itemClicked(int position) {
for(int i = 0; i < mItemsChecked.size(); i++) {
if(mItemsChecked.get(i) == position) {
mItemsChecked.remove(i);
return;
}
}
mItemsChecked.add(position);
}
}
This is OnItemClickListener for your ListView:
final ListView lv = (ListView)findViewById(R.id.listView1); // Your ListView name
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
((MySimpleCursorAdapter)lv.getAdapter()).itemClicked(position);
lv.getAdapter().notifyDataSetChanged(); // Because we need to call getView() method for all visible items in ListView, so that they are updated
}
});
Just remember to disable your CheckBox so that user can't click it.
Now you can see it as a little hack, because user doesn't click CheckBox at all - application sees it as clicking in specific ListView item, which in turn automatically checks appropriate CheckBox for you.

Here is simple example that will help you to implement that scenario
http://www.mysamplecode.com/2012/07/android-listview-checkbox-example.html

Related

Android ListView :: Scrolling ListView while item is selected causes display problems

Alright, so I'm using a ListView with a custom adapter. Everything works fine and dandy...until the user selects a ListView row and tries to scroll.
When the user selects a row, the background color of that row changes to blue (which is good).
But, problems occur when we begin scrolling: When we scroll past the selected row, the blue fixes itself to either the bottom or the top of the ListView, depending on which way we were scrolling.
Selected row changes color on touch (good)
Part of the background of selected row is fixed to top when scrolling down (not good)
Part of the background of selected row is fixed to bottom when scrolling up (not good)
Here is my source code:
List View that I'm populating dynamically
<ListView
android:id="#+id/tallyDataListView"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:divider="#000000"
android:dividerHeight="1dp"
android:fadeScrollbars="false"
android:listSelector="#0099FF" >
layout_list_view_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<View
android:focusable="false"
android:focusableInTouchMode="false"
style="#style/tableSideBorderLine" />
<TextView
android:id="#+id/COLUMN_PIPE_NUMBER"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
style="#style/tableColumn"
xmlns:android="http://schemas.android.com/apk/res/android" />
<View
android:focusable="false"
android:focusableInTouchMode="false"
style="#style/tableColumnDivider" />
<TextView
android:id="#+id/COLUMN_TOTAL_LENGTH"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
style="#style/tableColumn"
xmlns:android="http://schemas.android.com/apk/res/android" />
<View
android:focusable="false"
android:focusableInTouchMode="false"
style="#style/tableColumnDivider" />
<TextView
android:id="#+id/COLUMN_ADJUSTED"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
style="#style/tableColumn"
xmlns:android="http://schemas.android.com/apk/res/android" />
<View
android:focusable="false"
android:focusableInTouchMode="false"
style="#style/tableSideBorderLine" />
</LinearLayout>
My Custom Adapter
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.ArrayList;
public class ListViewAdapter extends ArrayAdapter<String>{
LayoutInflater inflater;
private final ArrayList<String> adjustedValues;
private final ArrayList<String> pipeNumbers;
private final ArrayList<String> totalLengthValues;
public ListViewAdapter(Activity pContext, ArrayList<String> pPipeNumbers,
ArrayList<String> pTotalLengthValues, ArrayList<String> pAdjustedValues)
{
super(pContext, R.layout.layout_list_view_row, pAdjustedValues);
adjustedValues = pAdjustedValues;
pipeNumbers = pPipeNumbers;
totalLengthValues = pTotalLengthValues;
inflater = pContext.getLayoutInflater();
}
#Override
public View getView(int pPosition, View pView, ViewGroup pParent)
{
View view = inflater.inflate(R.layout.layout_list_view_row, pParent, false);
TextView col1 = (TextView)view.findViewById(R.id.COLUMN_PIPE_NUMBER);
col1.setText(pipeNumbers.get(pPosition));
TextView col2 = (TextView)view.findViewById(R.id.COLUMN_TOTAL_LENGTH);
col2.setText(totalLengthValues.get(pPosition));
TextView col3 = (TextView)view.findViewById(R.id.COLUMN_ADJUSTED);
col3.setText(adjustedValues.get(pPosition));
return view;
}
}
This is the common problem about the listview. When you scroll down it creates the new view every time. That is why the selected element from the top gets out of the focus and another element is selected.
For this problem you have to extend the BaseAdapter class and
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Vehical vehical = vehicals.get(position);
ViewHolder viewHolder = null;
if(convertView==null)
{
viewHolder = new ViewHolder();
convertViewactivity.getLayoutInflater().inflate(R.layout.list_item,null);
convertView.setTag(viewHolder);
}
else
{
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.tvVehicalName = (TextView) convertView.findViewById(R.id.vehicle_name);
viewHolder.tvVehicalName.setText(vehical.getVehicalName());
if(vehical.isSelected()){
viewHolder.tvVehicalName.setTextColor(Color.RED);
}
else
{
viewHolder.tvVehicalName.setTextColor(Color.BLACK);
}
return convertView;
}
//On listener of the listview
searchList.setOnItemClickListener(
new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3) {
if(searchAdapter.isItemSelected(position))
{
searchAdapter.setSelectedItem(position,false);
selectedList.remove(((Vehical)searchAdapter.getItem(position)).getVehicalName());
}
else
{
if(selectedList.size()<new_vehiclelimit){
searchAdapter.setSelectedItem(position,true);
selectedList.add(((Vehical)searchAdapter.getItem(position)).getVehicalName());
}
else
{
Toast.makeText(getApplicationContext(), "Vechicle Limit is Over", Toast.LENGTH_SHORT).show();
}
}
Keep a reference for selected row position in your Adapter, say
int selectedPos = -1;
The value will be -1 when no row is selected. And in the OnItemClickListener of the listview,update selectedPos with the clicked position and call notifyDatasetChanged() on the adapter. In the getView method of the adapter, check for the selectedPos value and highlight the row accordingly.

Android: button showing up multiple times in list view

I trying to write code to highlight the selected value of the list with "Next" button at the bottom of the layout. But for some reason, after every list item, "next" button also shows up. Can someone please help me resolve this problem?
Here is the layout file:
<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="vertical"
android:id="#+id/questionLayout"
>
<TextView android:id="#+id/txtExample"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="25sp"
android:textColor="#000000"
android:background="#FF0000"
/>
<ListView
android:id="#+id/listExample"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#CCCCCC"
android:choiceMode="singleChoice"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<Button
android:id = "#+id/next"
android:text="Next"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_gravity="center"
android:layout_weight="50"
/>
<Button
android:id = "#+id/submit"
android:text="Submit"
android:layout_width = "0dp"
android:layout_height = "wrap_content"
android:layout_weight="50"
android:layout_gravity="center"
/>
</LinearLayout>
</LinearLayout>
Java Code:
public class updateList extends Activity {
private SelectedAdapter selectedAdapter;
private ArrayList<String> list;
int correct_answer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = new ArrayList<String>();
list.add("Choice One");
list.add("Choice Two");
list.add("Choice Three");
selectedAdapter = new SelectedAdapter(this,0,list);
selectedAdapter.setNotifyOnChange(true);
ListView listview = (ListView) findViewById(R.id.listExample);
listview.setAdapter(selectedAdapter);
listview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view,
int position, long id) {
// user clicked a list item, make it "selected"
selectedAdapter.setSelectedPosition(position);
}
});
}
}
Thanks in advance
SSP
Selected Adaptor class:
public class SelectedAdapter extends ArrayAdapter{
// used to keep selected position in ListView
private int selectedPos = -1; // init value for not-selected
public SelectedAdapter(Context context, int textViewResourceId,
List objects) {
super(context, textViewResourceId, objects);
}
public void setSelectedPosition(int pos){
selectedPos = pos;
// inform the view of this change
notifyDataSetChanged();
}
public int getSelectedPosition(){
return selectedPos;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
// only inflate the view if it's null
if (v == null) {
LayoutInflater vi = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.activity_main, null);
}
// get text view
TextView label = (TextView)v.findViewById(R.id.txtExample);
// change the row color based on selected state
if(selectedPos == position){
label.setBackgroundColor(Color.CYAN);
}else{
label.setBackgroundColor(Color.WHITE);
}
label.setText(this.getItem(position).toString());
/*
// to use something other than .toString()
MyClass myobj = (MyClass)this.getItem(position);
label.setText(myobj.myReturnsString());
*/
return(v);
}
}
change your listview in xml as like this
<ListView
android:id="#+id/listExample"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"//===== set maximum heighthere
android:layout_marginBottom="50dp"// === give some space at bottom so that buttons will appear
android:background="#CCCCCC"
android:choiceMode="singleChoice"
/>
But for some reason, after every list item, "next" button also shows up.
The ListView's row layout is determined by the layout you inflate in getView() or pass to your Adapter's super class if you haven't overridden getView(). Double check this layout and remove the unwanted code.
Addition
The layout for your ListView's items only needs to be one TextView since you only want to display a phrase in each. However you are currently passing your entire main layout, this creates the Buttons, an unused ListView, and everthing else in every row...
Instead use android.R.layout.simple_list_item_1 in getView(), of course you'll need to change the id you pass to findViewById() as well:
if (v == null) {
LayoutInflater vi = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(android.R.layout.simple_list_item_1, null);
}
// get text view
TextView label = (TextView)v.findViewById(android.R.id.text1);
Please watch Android's Romain Guy discuss writing an efficient adapter to speed things up.

Not able to add Title bar for Listview

The requirement for my screen is like having a title bar at the top middle and followed by the list view when am trying to do that am not able to do like i got state name in every list item.I want that only in the top and once. And the screen shot of it is
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TableRow>
<TextView
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:background="#000000"
android:text="Select State"
></TextView>
</TableRow>
<TableRow>
<TextView android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:id="#+id/label"
android:textSize="30px"></TextView>
</TableRow>
</TableLayout>
I have tried many ways this is my present layout
and my java code is
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class new21 extends ListActivity {
/** Called when the activity is first created. */
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Create an array of Strings, that will be put to our ListActivity
String[] names = new String[] { "Andhra Pradesh", "Kerala","Tamilnadu","Karnataka" };
// Use your own layout and point the adapter to the UI elements which
// contains the label
this.setListAdapter(new ArrayAdapter<String>(this, R.layout.new21,
R.id.label, names));
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
// Get the item that was clicked
Object o = this.getListAdapter().getItem(position);
String keyword = o.toString();
if(keyword.equals("Andhra Pradesh"))
{
Intent ima45=new Intent(new21.this,new31.class);
startActivity(ima45);
}
Toast.makeText(this, "You selected: " + keyword, Toast.LENGTH_LONG)
.show();
}
}
Can any one help me.
You can addHeader to the ListView like this,
View header = getLayoutInflater().inflate(R.layout.header, null);
ListView listView = getListView();
listView.addHeaderView(header);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_single_choice, names));
Where R.layout.header is the layout that contains a TextView with text "Select State"
UPDATED:
public class ListViewProblemActivity extends ListActivity {
ListView listView;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Create an array of Strings, that will be put to our ListActivity
String[] names = new String[] { "Andhra Pradesh", "Kerala","Tamilnadu","Karnataka" };
// Use your own layout and point the adapter to the UI elements which
// contains the label
TextView tv = new TextView(getApplicationContext());
tv.setText("Select State");
listView = getListView();
listView.addHeaderView(tv);
this.setListAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1,names));
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
// Get the item that was clicked
if(position != 0){
System.out.println(position - 1);
Object o = this.getListAdapter().getItem(position - 1);
String keyword = o.toString();
Toast.makeText(this, "You selected: " + keyword, Toast.LENGTH_LONG)
.show();
}
}
}
Usey only a ListView in your activity, remove the heading there. Then use ListView.addHeaderViwe(); to add a header to the Listview. This Header is display before the first item.
See the documentaton for further information.
you better use ListView.addHeaderViwe();
but don't forget to remove what u did "extends ListActivity", no need for that,
and also remove title from your "new21.xml"
in your xml, just fix the text item u want to show in every row of the list,
You are doing fully wrong. Just take a LinearLayout with one TextView (for Title bar) and ListView (To display listview), nothing more than these 2 views.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:background="#000000"
android:text="Select State">
</TextView>
<ListView
android:id="#+id/lviewState"
android:layout_height="wrap_content"
android:layout_width="match_parent">
</ListView>
</LinearLayout>
Now, follow your code to display ListView.

Removing an Item with a Button in ListView with Custom ArrayAdapter

I have custom list_row :
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content" android:baselineAligned="false">
<Button android:layout_width="30dip" android:layout_marginTop="7dip" android:gravity="right"
android:id="#+id/delete" android:layout_height="30dip" android:background="#drawable/delete"
android:layout_gravity="top"></Button>
<TextView android:textSize="20dip"
android:text="TextView" android:id="#+id/tavsiye" android:layout_marginTop="10dip"
android:layout_gravity="top" android:layout_width="wrap_content"
android:layout_height="wrap_content"></TextView>
</LinearLayout>
I have a ListView like that:
<ListView
android:id="#+id/tavsiyeler"
android:layout_height="300dip"
android:layout_width="170dip"
android:fastScrollEnabled="true"
android:scrollbars="vertical"/>
and a custom adapter which extends ArrayAdapter :
public class HekimTavsiyeleriAdapter extends ArrayAdapter<String> {
private Context context;
private int resource;
private ArrayList<String> tavsiyeler;
public HekimTavsiyeleriAdapter(Context context, int resource,
ArrayList<String> objects) {
super(context, resource, objects);
this.context=context;
this.resource=resource;
this.tavsiyeler=objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(this.resource, null);
}
if (this.tavsiyeler.size()!=0) {
TextView tavsiye = (TextView) v.findViewById(R.id.tavsiye);
Button but= (Button) v.findViewById(R.id.delete);
if (tavsiye != null) {
String st=this.tavsiyeler.get(position);
tavsiye.setText(st);
}
if( but!=null){
but.setId(position);
but.setOnClickListener(new AdapterView.OnClickListener() {
#Override
public void onClick(View v) {
int id=v.getId();
tavsiyeler.remove(id);
notifyDataSetChanged();
}
});
}
}
return v;
}
I am creating adapter and fill the list like that :
eklenecekTavsiyeler=new ArrayList<String>();
adapter= new HekimTavsiyeleriAdapter(context,
R.layout.hekim_tavsiyeleri_row, eklenecekTavsiyeler);
ListView tavsiyelerListesi = (ListView)findViewById(R.id.tavsiyeler);
tavsiyelerListesi.setAdapter(adapter);
And adding new items like that:
this.adapter.add(<some-string>);
this.adapter.notifyDataSetChanged();
and my list view is seen like that:
http://imageshack.us/photo/my-images/97/listir.jpg/
Here is my question:
I am adding new items to the list. I have fixed height for the list. When I fill the list until all height is occupied, then I add one new item to the list which requires scrolling becasue overflow in list height. The last item I added gets wrong id and when I pressed the cross button, it removes wrong item. However, when the list is not overflowed, everything works fine. After overflow, the ids of buttons are set wrongly (seems randomly). By the way, for setting the button's id, I am using getView's position argument.
Thanks in advance.
I am afraid that you have flaw in the code.
You have to stop calling but.setId(). With this you are overriding internal id of the view which is the value of R.id.delete. Probably you meant to use but.setTag() / but.getTag()?

How can I show a combobox in Android? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
How can I show a combobox in Android?
In android it is called a Spinner you can take a look at the tutorial here.
Hello, Spinner
And this is a very vague question, you should try to be more descriptive of your problem.
Here is an example of custom combobox in android:
package myWidgets;
import android.content.Context;
import android.database.Cursor;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AutoCompleteTextView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.SimpleCursorAdapter;
public class ComboBox extends LinearLayout {
private AutoCompleteTextView _text;
private ImageButton _button;
public ComboBox(Context context) {
super(context);
this.createChildControls(context);
}
public ComboBox(Context context, AttributeSet attrs) {
super(context, attrs);
this.createChildControls(context);
}
private void createChildControls(Context context) {
this.setOrientation(HORIZONTAL);
this.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
_text = new AutoCompleteTextView(context);
_text.setSingleLine();
_text.setInputType(InputType.TYPE_CLASS_TEXT
| InputType.TYPE_TEXT_VARIATION_NORMAL
| InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
| InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE
| InputType.TYPE_TEXT_FLAG_AUTO_CORRECT);
_text.setRawInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
this.addView(_text, new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, 1));
_button = new ImageButton(context);
_button.setImageResource(android.R.drawable.arrow_down_float);
_button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
_text.showDropDown();
}
});
this.addView(_button, new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
}
/**
* Sets the source for DDLB suggestions.
* Cursor MUST be managed by supplier!!
* #param source Source of suggestions.
* #param column Which column from source to show.
*/
public void setSuggestionSource(Cursor source, String column) {
String[] from = new String[] { column };
int[] to = new int[] { android.R.id.text1 };
SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(this.getContext(),
android.R.layout.simple_dropdown_item_1line, source, from, to);
// this is to ensure that when suggestion is selected
// it provides the value to the textbox
cursorAdapter.setStringConversionColumn(source.getColumnIndex(column));
_text.setAdapter(cursorAdapter);
}
/**
* Gets the text in the combo box.
*
* #return Text.
*/
public String getText() {
return _text.getText().toString();
}
/**
* Sets the text in combo box.
*/
public void setText(String text) {
_text.setText(text);
}
}
Hope it helps!!
Not tested, but the closer you can get seems to be is with AutoCompleteTextView. You can write an adapter wich ignores the filter functions. Something like:
class UnconditionalArrayAdapter<T> extends ArrayAdapter<T> {
final List<T> items;
public UnconditionalArrayAdapter(Context context, int textViewResourceId, List<T> items) {
super(context, textViewResourceId, items);
this.items = items;
}
public Filter getFilter() {
return new NullFilter();
}
class NullFilter extends Filter {
protected Filter.FilterResults performFiltering(CharSequence constraint) {
final FilterResults results = new FilterResults();
results.values = items;
return results;
}
protected void publishResults(CharSequence constraint, Filter.FilterResults results) {
items.clear(); // `items` must be final, thus we need to copy the elements by hand.
for (Object item : (List) results.values) {
items.add((String) item);
}
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}
}
... then in your onCreate:
String[] COUNTRIES = new String[] {"Belgium", "France", "Italy", "Germany"};
List<String> contriesList = Arrays.asList(COUNTRIES());
ArrayAdapter<String> adapter = new UnconditionalArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line, contriesList);
AutoCompleteTextView textView = (AutoCompleteTextView)
findViewById(R.id.countries_list);
textView.setAdapter(adapter);
The code is not tested, there can be some features with the filtering method I did not consider, but there you have it, the basic principles to emulate a ComboBox with an AutoCompleteTextView.
Edit
Fixed NullFilter implementation.
We need access on the items, thus the constructor of the UnconditionalArrayAdapter needs to take a reference to a List (kind of a buffer).
You can also use e.g. adapter = new UnconditionalArrayAdapter<String>(..., new ArrayList<String>); and then use adapter.add("Luxemburg"), so you don't need to manage the buffer list.
The questions is perfectly valid and clear since Spinner and ComboBox (read it: Spinner where you can provide a custom value as well) are two different things.
I was looking for the same thing myself and I wasn't satisfied with the given answers. So I created my own thing. Perhaps some will find the following hints useful. I am not providing the full source code as I am using some legacy calls in my own project. It should be pretty clear anyway.
Here is the screenshot of the final thing:
The first thing was to create a view that will look the same as the spinner that hasn't been expanded yet. In the screenshot, on the top of the screen (out of focus) you can see the spinner and the custom view right bellow it. For that purpose I used LinearLayout (actually, I inherited from Linear Layout) with style="?android:attr/spinnerStyle". LinearLayout contains TextView with style="?android:attr/spinnerItemStyle". Complete XML snippet would be:
<com.example.comboboxtest.ComboBox
style="?android:attr/spinnerStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="#+id/textView"
style="?android:attr/spinnerItemStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:singleLine="true"
android:text="January"
android:textAlignment="inherit"
/>
</com.example.comboboxtest.ComboBox>
As, I mentioned earlier ComboBox inherits from LinearLayout. It also implements OnClickListener which creates a dialog with a custom view inflated from the XML file. Here is the inflated view:
<?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:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<EditText
android:id="#+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:hint="Enter custom value ..." >
<requestFocus />
</EditText>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="OK"
/>
</LinearLayout>
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
There are two more listeners that you need to implement: onItemClick for the list and onClick for the button. Both of these set the selected value and dismiss the dialog.
For the list, you want it to look the same as expanded Spinner, you can do that providing the list adapter with the appropriate (Spinner) style like this:
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(
activity,
android.R.layout.simple_spinner_dropdown_item,
states
);
More or less, that should be it.
Custom made :)
you can use dropdown hori/vertical offset properties to position the list currently,
also try android:spinnerMode="dialog" it is cooler.
Layout
<LinearLayout
android:layout_marginBottom="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<AutoCompleteTextView
android:layout_weight="1"
android:id="#+id/edit_ip"
android:text="default value"
android:layout_width="0dp"
android:layout_height= "wrap_content"/>
<Spinner
android:layout_marginRight="20dp"
android:layout_width="30dp"
android:layout_height="50dp"
android:id="#+id/spinner_ip"
android:spinnerMode="dropdown"
android:entries="#array/myarray"/>
</LinearLayout>
Java
//set auto complete
final AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.edit_ip);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, getResources().getStringArray(R.array.myarray));
textView.setAdapter(adapter);
//set spinner
final Spinner spinner = (Spinner) findViewById(R.id.spinner_ip);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
textView.setText(spinner.getSelectedItem().toString());
textView.dismissDropDown();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
textView.setText(spinner.getSelectedItem().toString());
textView.dismissDropDown();
}
});
res/values/string
<string-array name="myarray">
<item>value1</item>
<item>value2</item>
</string-array>
Was that useful??
For a combobox (http://en.wikipedia.org/wiki/Combo_box) which allows free text input and has a dropdown listbox I used a AutoCompleteTextView as suggested by vbence.
I used the onClickListener to display the dropdown list box when the user selects the control.
I believe this resembles this kind of a combobox best.
private static final String[] STUFF = new String[] { "Thing 1", "Thing 2" };
public void onCreate(Bundle b) {
final AutoCompleteTextView view =
(AutoCompleteTextView) findViewById(R.id.myAutoCompleteTextView);
view.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
view.showDropDown();
}
});
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_dropdown_item_1line,
STUFF
);
view.setAdapter(adapter);
}

Categories

Resources