Limit AutoCompleteTextView to only one result - android

I'm using AutoCompleteTextView with a custom layout for the adapter. The problem is I don't know how to limit the results for only one at time, like in the default Layout.
I read that It's possible limiting the height, but doesn't work in all screens. Thanks for your attention.
I've this on my activity_main layout.
<AutoCompleteTextView android:id="#+id/autotext"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:minWidth="480dp"
android:layout_weight="1"
android:maxLength="23"
android:maxLines="1"
android:textColor="#000000" />
And this is the adapter's layout.
<TextView android:id="#+id/textpop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="17sp"/>

Have a look at this code. It's basically the code for the SDK ArrayAdapter class with a small modification(which doesn't count). If you want to show only one suggestion in the AutoCompleteTextView then you could make a small modification to the class from the link, to the performFiltering() method like this:
// ... the rest of that method
if (newValues.size() > 1) { // if we have more than an item in the list
// get the first suggestion
T oneItem = newValues.get(0);
// empty the suggestion list
newValues.clear();
// add the only suggestion.
newValues.add(oneItem);
}
results.values = newValues;
results.count = newValues.size();

I found the above answer unsatisfactory, and the link is dead.
For the simplest way to do this, create a custom adapter and simply force the count to 1
class SingleArrayAdapter extends ArrayAdapter<String> {
public SingleArrayAdapter(Context context, int resource, String[] objects) {
super(context, resource, objects);
}
#Override
public int getCount() {
return 1;
}
}

You can create your own AutoCompleteTextView adapter which implement Filterable interface, or extend existing adapter, but override getFilter() method, create your own filter implementation, then you can customize filter logic and return any number of results you like.
You can refer to the ArrayFilter implementation in ArrayAdpater for reference.

Related

How to refresh listview in android without scrolling

I am dynamically adding items to my listview my code works fine but my problem is when the listview is updated it is going to the starting position (items are added but scroll view begins from initial position).I am using listview inside fragment.I want to avoid that scrolling to initial position.
CODE
ListAdapter adapter =
new SimpleAdapter(getContext(), productsList, R.layout.list_notify, new String[]{"id","title","des"},
new int[]{R.id.id, R.id.title,R.id.des});
lv.setAdapter(adapter);
lv.invalidateViews();
Reference : How to refresh Android listview?
ListView Refresh in Android
Refresh Listview in android
Android refresh listview in fragment
How to refresh Android listview?
ListView is officially legacy. Try to use RecyclerView then you will be able to tell that you don't update whole list with methods like notifyItemChanged(position)...
In your case you will call notifyItemRangeInserted(position, count)
https://developer.android.com/guide/topics/ui/layout/recyclerview
Try smoothScrollToPosition on your listview.
See this, pretty similar if I understand correct what you want.
So in order to get that scrolling to stop you basically have to block the listview from laying out its children so first off you have to create a custom listview something like
public class BlockingListView extends ListView {
private boolean mBlockLayoutChildren;
public BlockingListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setBlockLayoutChildren(boolean block) {
mBlockLayoutChildren = block;
}
#Override
protected void layoutChildren() {
if (!mBlockLayoutChildren) {
super.layoutChildren();
}
}
}
then you can use it like this for example
int firstVisPos = mListView.getFirstVisiblePosition();
View firstVisView = mListView.getChildAt(0);
int top = firstVisView != null ? firstVisView.getTop() : 0;
// Block children layout for now
mListView.setBlockLayoutChildren(true);
// Number of items added before the first visible item
int itemsAddedBeforeFirstVisible = ...;
// Change the cursor, or call notifyDataSetChanged() if not using a Cursor
mAdapter.swapCursor(...);
// Let ListView start laying out children again
mListView.setBlockLayoutChildren(false);
// Call setSelectionFromTop to change the ListView position
mListView.setSelectionFromTop(firstVisPos + itemsAddedBeforeFirstVisible, top);
the setBlockLayoutChildren being true is what will stop your listview from scrolling and of course you can set whatever else you would like it to do
you may also just want to look into recyclerview though may make your life easier
I used a gridview instead of my listview and it solved my problem
set 1 item per row can act as listview in my code
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/grid"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
**android:numColumns="1"**
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:scrollbarStyle="outsideOverlay"
android:verticalScrollbarPosition="right"
android:scrollbars="vertical">
reference : Custom layout as an item for a grid view

How to prevent ListView with two columns from drawing to the size of ArrayList passed (prevent populating empty items)?

I have a custom ListView Adaper that has two columns. It accepts an ArrayList and populate its content in two columns.
My adapter class is like this
public class myAdapter extends ArrayAdapter<String []> {
private final Activity activity;
private final ArrayList<String []> myArray;
public myAdapter(Activity activity,ArrayList<String[]> arraylist){
super(activity,R.layout.customListview,arraylist);
this.activity = activity;
this.myArray = arraylist;
}
#Override
public View getView(final int position,View view, ViewGroup parent){
LayoutInflater inflater = activity.getLayoutInflater();
View rowView = inflater.inflate(R.layout.customListview, null, true);
if (position < (myArray.size()/2)){
textview1.setText(myArray.get(position*2)[0]);
textview2.setText(myArray.get((position*2)+1)[0]);
}
else {
LinearLayout listRow = (LinearLayout)rowView.findViewById(R.id.listRow);
listRow.setVisibility(View.GONE);
textvew1.setVisibility(View.GONE);
textvew2.setVisibility(View.GONE);
}
return rowView;
}
My listview is displaying contents properly. But there is a blank space below my listview. I think it is populating null elements with list item for the size of the array passed. Since I am displaying the contents of my array in two columns, I need the size of listview to be only the half of my array. Any suggestions?
Thanks in advance.This happens if i pass array with 2 elements
Here is the customListview.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:id="#+id/listRow"
android:orientation="horizontal"
android:weightSum="1">
<TextView
android:layout_weight="0.5"
android:layout_width="0sp"
android:layout_height="match_parent"
android:textAlignment="center"
android:id="#+id/text1"
android:layout_marginRight="10dp"/>
<TextView
android:layout_weight="0.5"
android:layout_width="0sp"
android:layout_height="match_parent"
android:textAlignment="center"
android:id="#+id/text2"
android:layout_marginLeft="10dp"/>
</LinearLayout>
just override getCount() inside your adapter and set the list length
#Override
public int getCount() {
return myArray.size() / 2;
}
As #nbaroz mentioned in his answer you should override getCount() and return a custom value based on the content inside of myArray. Further more, it seems that since you only want your ListView to contain two rows you should only return 2 from getCount(). This way it will always only have two cells.
Based on what I understand from your description, you are trying to create a layout similar to the Play store; where you have several rows and in each row you have several individual columns. This can be done with only one data structure (ArrayList or LinkedList) to make the design easier. You would do this by having the data structure length be the amount of rows (this is better than hard-coding a value) you want to display. The items inside of the data structure would be of a custom object type that contains the data necessary for populating the columns inside of each row.
Example Custom ListView item object:
public class MyCustomRowObject {
public Column column1;
public Column column2;
public Column column2;
public Column getColumn1() {
return column1;
}
public Column getColumn2() {
return column2;
}
public Column getColumn3() {
return column3;
}
Inside of getView(...) you would get a reference of MyCustomRowObject and create your custom list item that contains the individual views for the columns of the row. Once the list item is inflated, use the data from MyCustomRowObject reference to populate the views data fields and return the list item. Viola!
Also note
This will incur a lot of overhead inflating all of these views so you definitely will want to using the view recycling pattern if you have any content that scroll of screen. Personally, I would use the recycling pattern always even if I don't have a lot of list data because it makes it future proof.

Android List View with BaseAdapter Drag and Drop sort

I have a list of records in a listview that I want the user to be able to re-sort using a drag and drop method. I am using BaseAdapter for that listview.
I have not found a tutorial for it. Can anyone point me to some code for doing this?
There are working set of codes for Drag-and-Drop using ListView by a starting developer in Google team # ListViewDraggingAnimation zip. There is a video explaining the internal code # ListView Cell Dragging and Rearranging. You don't have to understand the code in DynamicListView.
Sample code to start:
StableArrayAdapter adapter = new StableArrayAdapter(this, R.layout.text_view, mCheeseList);
DynamicListView listView = (DynamicListView) findViewById(R.id.listview);
listView.setCheeseList(mCheeseList);
listView.setAdapter(adapter);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
Notes:
For calling StableArrayAdapter constructor using "this" object works in an Activity. If on Fragment subclass, use getContext() or similar.
ArrayList mCheeseList is an example. Use another list that is appropriate for your code. Personally I would like to use my own custom class instead of the simple ArrayList
Again if you're using Fragment like me, use view.findViewById instead of just findViewById method call.
Finally, maybe most important is the sample uses the popular ArrayAdapter subclass, StableArrayAdapter. This could be easily changed to using BaseAdapter subclass instead (fitting your code). You'll have to pass the data to StableArrayAdapter somehow, and that's the main thing. Interestingly, the only code that uses ArrayAdapter in StableArrayAdapter class is the getItem method call.
I found an interesting sample of BaseAdapter subclass code that looks good # Stackoverflow Drag and Drop for listview of views. This probably deserves more attention.
Personally this is my first time implementing Drag-and-Drop function. The code offers a rather simple example with one TextView. I need to customize it using 3 UI elements in my layout instead of just one. I think I can customize Google's sample code to my own needs, a common goal.
I hope this post and my notes will help others since Drag-and-Drop functionality has not been developed into the Android SDK, and sorely needs one.
Good luck and have fun...Tommy Kwee
Use arraylist of your Model.
private ArrayList<YourModel> albumList = new ArrayList<YourModel>();
//add item in your list.
DragSortListView listView = (DragSortListView) findViewById(R.id.lv_test);
ReorderAlbumAdapter adapter = new ReorderAlbumAdapter(this, albumList);
listView.setAdapter(adapter);
listView.setDropListener(onDrop);
listView.setRemoveListener(onRemove);
private DragSortListView.DropListener onDrop = new DragSortListView.DropListener() {
#Override
public void drop(int from, int to) {
if (from != to) {
AlbumModel item = adapter.getItem(from);
adapter.remove(item);
adapter.insert(item, to);
}
}
};
private DragSortListView.RemoveListener onRemove = new DragSortListView.RemoveListener() {
#Override
public void remove(int which) {
adapter.remove(adapter.getItem(which));
}
};
XML for listview is:
<com.mobeta.android.dslv.DragSortListView
android:id="#+id/lv_test"
android:layout_width="match_parent"
android:layout_height="match_parent"
dslv:collapsed_height="2dp"
dslv:drag_enabled="true"
dslv:drag_handle_id="#drawable/ic_launcher"
dslv:drag_scroll_start="0.33"
dslv:drag_start_mode="onMove"
dslv:float_alpha="0.6"
dslv:max_drag_scroll_speed="0.5"
dslv:remove_enabled="true"
dslv:remove_mode="flingRemove"
dslv:slide_shuffle_speed="0.3"
dslv:sort_enabled="true"
dslv:track_drag_sort="false"
dslv:use_default_controller="true" />
You should use arrayadapter for your model. Hope it will help you.
Here is the link for your listview that provides DragDrop functionality.Check This link
replace your listview with
<com.terlici.dragndroplist.DragNDropListView
android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
in your activity class
DragNDropListView list = (DragNDropListView)findViewById(android.R.id.list);
DragNDropCursorAdapter adapter = new DragNDropCursorAdapter(context,
R.layout.row,
cursor,
new String[]{"text"},
new int[]{R.id.text},
R.id.handler);
list.setDragNDropAdapter(adapter);
it also provides drag drop interface,exactly what you want.
listView.setDropListener(onDrop);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
private DragSortListView.DropListener onDrop = new DragSortListView.DropListener() {
#Override
public void drop(int from, int to) {
if (from != to) {
// DragSortListView list = listView;
YourModel item = adapter.getItem(from);
adapter.remove(item);
adapter.insert(item, to)
}
};
Add below methods in baseadapter
public void remove(YourModel item) {
aryList.remove(item);
notifyDataSetChanged();
}
public void insert(YourModel item, int position) {
aryList.add(position, item);
notifyDataSetChanged();
}
In Xml :
<com.mobeta.android.dslv.DragSortListView
android:id="#+id/lstvw"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="#null"
android:scrollbars="none"
dslv:collapsed_height="1px"
dslv:drag_enabled="true"
dslv:drag_handle_id="#+id/drag_handle1"
dslv:drag_scroll_start="0.33"
dslv:drag_start_mode="onDown"
dslv:float_alpha="0.6"
dslv:remove_enabled="false"
dslv:slide_shuffle_speed="0.3" />

Retrieve array from SQLite in listview with more than a colum (ANDROID)

So I want to create a listview that consists of more than a column. I already succeed called the database, but the layouting still not work. I think this is because the all my data are put in one array and its difficult to make them in three columns. anyone can find solution for me?
My program result is like this in listview:
John Doe 12 Argentina
Marilyn Rose 32 Russia
Annabella 19 United States
However what I want is more like this:
John Doe 12 Argentina
Marilyn Rose 32 Russia
Annabella 19 United States
From what I read, we will need 2 XMLs. One for listview, and another is for layouting (give space between text). And One .JAVA called adapter to connect my MainActivity.java and layouting XML.
add:
I already tried using two XMLs. one XML, lets call it main.XML is for calling ListView. And grid.XML, is where i put android:layout_alignParentLeft="true" (to create spaces).
I used MyAdapter.JAVA to convertview in grid.XML. and in MainActivity.JAVA i called MyAdapter. However my code in MainActivity became error when its connected it MyAdapter.
this was my code that gave error java.lang.RuntimeException. So I had to delete it.. more information about it, please check two last code...
MainActivity.java (error)
public static ArrayList<String> arraydealer = new ArrayList<String>();
MyAdapter bohwat = new MyAdapter(MainActivity.this, arraydealer);
lvcustom.setAdapter(bohwat);
And here is the code that is working well. It uses class MainActivity, AstraDB, and MySetGet, and main.XML. Other class thats not working is MyAdapter and grid.xml
This is how I called my database:
public class MainActivity extends Activity
{
public static ArrayList<String> arraydealer = new ArrayList<String>();
AstraDB astrahandler = new AstraDB(this);
Spinner spDealer;
ListView lvcustom;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lvcustom = (ListView)findViewById(R.id.custom_lv);
ShowListView();
}
private void ShowListView()
{
astrahandler.getAllDealer();
ArrayAdapter<String> adapt = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, arraydealer);
lvcustom.setAdapter(adapt);
}
}
This code of ArrayList in Activity and String name in AstraDB are very important to connect my MainActivity with the database but it seems this create trouble in layouting. because they are contained in ONE array
And this is function to get all data in my DB. its on AstraDB.java:
public List<MySetGet> getAllDealer()
{
List<MySetGet> info = new ArrayList<MySetGet>();
db = DBHelper.getReadableDatabase();
// Select All Query
String selectQuery = "SELECT * FROM Dealer";
cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
MySetGet lets = new MySetGet();
lets.setDealerID(Integer.parseInt(cursor.getString(0)));
lets.setDealerName(cursor.getString(1));
lets.setDealerOwner(cursor.getString(2));
lets.setDealerWil(cursor.getString(3));
String name = cursor.getInt(0) +
"\u00A0 "+ cursor.getString(1)+
"\u00A0 "+ cursor.getString(2)+
"\u00A0 "+ cursor.getString(3);
MainActivity.arraydealer.add(name);
//add
info.add(lets);
} while (cursor.moveToNext());
}
// closing connection
cursor.close();
db.close();
//return contentdealer;
return info;
}
The MySetGet in getAllDealer() connects with MySetGet.java where I put setter and getter so the data can become object. which is more like this:
public int getDealerID(){ return DealerID;}
public void setDealerID(int DealerID) { this.DealerID = DealerID; }
Code to connect other XML with Java but still gave error:
grid_dealer.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_height="wrap_content"
android:layout_width="50dp"
android:id="#+id/col1"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:text=""/>
<TextView
android:layout_height="wrap_content"
android:layout_width="100dp"
android:id="#+id/col2"
android:layout_toRightOf="#id/col1"
android:layout_centerVertical="true"
android:text=""/>
important code in MyAdapter.java:
public class MyAdapter extends BaseAdapter
{
Context context;
ArrayList<MySetGet> dealerlist;
public MyAdapter(Context context, ArrayList<MySetGet>list)
{
this.context = context;
dealerlist = list;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
MySetGet yay = dealerlist.get(position);
//this is to customize the layout of the listview
if(convertView == null)
{
LayoutInflater inflater = null;
inflater = (LayoutInflater)context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.grid_dealer, null);
}
TextView tvID = (TextView)convertView.findViewById(R.id.col1);
tvID.setText(yay.getDealerID());
TextView tvName = (TextView)convertView.findViewById(R.id.col2);
tvName.setText(yay.getDealerName());
TextView tvOwner = (TextView)convertView.findViewById(R.id.col3);
tvOwner.setText(yay.getDealerOwner());
return convertView;
}
}
Please help me. I am very new to this. Is there a way to modify my code without changing too much on how I called my database? The class and XML below works fine in showing database, but didnt create a neat layout space between columns
Working class : AstraDB, MainActivity, MySetGet
Working XML : main.xml
Im sorry, if the post becomes longer. I want to clarify several things so that there is no misunderstanding.
you can use android:layout_weight="" for better arrangement of views
Using SimpleCursorAdapter is the ideal solution in your case. Please checkout a tutorial here that will take you through the steps in achieving what you want.
In simple_list_item_1 layout if you arrange items relative to each other you will get the result what you are getting now. If you want proper formatting, relate the elements to left, center and right using android:layout_alignParentLeft="true", android:centerHorizontal="true" and android:layout_alignParentRight="true" respectively

Android :how to set Fixed no(5 ) of Rows shows in ListView then after Scroll?

how to set Fixed no of Rows shows in ListView ? i want to set 5 Rows only show in Listview not all Rows. so how can i achive this Goal?
yes, you can achieve via adapter class, Try with following code in your adapter class.
public int getCount() {
return 5;
}
If you set this, the adapter class load only 5 items.
This can be achieved by setting the row item height to fixed dps and the List View height to be 5 times of row height in exact dps.
Here it is how I did it:
Step 1: Set fixed height to the item list ITEM_LIST_HEIGHT
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="25dp">
</TextView>
Step 2: Set fixed height to the list, more exactly LIST_HEIGHT = NUMBER_OF_ITEMS_TO_DISPLAY x ITEM_LIST_HEIGHT. For example for 6 items 150;
<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:layout_width="wrap_content"
android:layout_height="150dp"/>
I hope it helps !
You can custom your adapter. But I think your idea is SET MAX ITEM OF LIST VIEW. (I think it will better).
So you will custom your adapter look like:
private class CustomAdapter<T> extends ArrayAdapter<T> {
private static final int MAX_ROW_DISPLAY = 5;
private List<T> mItems;
public CustomAdapter(Context context, int resource, List<T> objects) {
super(context, resource, objects);
mItems = objects;
}
#Override
public int getCount() {
if (mItems == null) {
return 0;
}
return Math.min(MAX_ROW_DISPLAY, mItems.size());
}
}
Hope this help u !

Categories

Resources