Say i have an Array list called listitem which updates every time a GridView is clicked.
It gets the item of the GridView that was clicked and adds it to the array list, which is also used as the backing array for an adapter of a ListView.
That works fine but instead of adding the same rows to the ListView, I want to display a message like item_clicked (2) when it was clicked twice,
and if its clicked again display item_clicked (3) and so on.
I tried to approach this with this code:
public void addItems(int position) {
if (listItems.contains(value.get(position))) {
int index = listItems.indexOf(value.get(position));
listItems.set(index,value.get(position)); <- here
} else {
listItems.add(value.get(position));
adapter.notifyDataSetChanged();
}
}
position is the index of the GridView and values is an array of the values of the GridView.
This is my GridView code:
int index = 0;
while (rs.next()) {
value.add("ID :" + rs.getString(1) + " Nombre:" + rs.getString(3));
list2.add(values.get(index));
index++;
Log.w("query result: ", rs.getString(1));
}
ArrayAdapter adapter = new ArrayAdapter(papeleta_act.this, R.layout.list_item, list2);
grid.setAdapter(adapter);
grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
addItems(position);
}
});
} catch (Exception e) {
Log.w("My error;", e);
}
}
I would appreciate any idea of how to approach this prob.
Thanks in advance!
For the sake of simplicity, let's assume all items in the GridView are of a single type, and let's call it A. In this case, the ArrayList holds items of type A.
A simple solution would be to have listitem contain objects of a type that wrap A and also have a counter, for the times clicked. Possible implementation is:
public class B {
public A mA;
public int times_clicked;
}
How to show the times clicked in the ListView depends on your implementation of the layout. The default behavior of an ArrayAdapter is to check if the root element of the layout it was given is a TextView, and then set its text to the result of the toString() function of the item it is showing, so you could add this method to class B:
public String toString(){
if(times_clicked == 1 && A != null)
return A.toString();
else
return "item_clicked ("+times_clicked+")";
}
I have a ListView, where the row layout has TextView with two lines limit:
android:lines="2"
So, by default each ListView row displayed like:
this is line 1 of the row 1
this is line 2 of the row 1
---------------------------
this is line 1 of the row 2
this is line 2 of the row 2
I would like to show/hide all lines for the particular row, when user clicks on the row. Let's say user clicked on the row 1, I would like to show something like:
this is line 1 of the row 1
this is line 2 of the row 1
this is line 3 of the row 1
this is line 4 of the row 1
---------------------------
this is line 1 of the row 2
this is line 2 of the row 2
I was thinking about ExpandableListView usage, but seems its purpose is different.
How can I implement what I am looking for?
Im assuming you have a custom list adapter and a list view item layout.
Wrap all of your lines in some layout.
Give that layout an ID.
Reference the ID in your code and create a view object for it.
Implement a method of your list adapter that does something like:
public void toggleVisible() {
if (viewContainingLines.getVisibility() == View.VISIBLE)
viewContainingLines.setVisibility(View.INVISIBLE);
else
viewContainingLines.setVisibility(View.VISIBLE);
}
attach an onItemClickListener to the list view.
And do something to the effect of - When a user clicks an item, call a that function in your list adapter that toggles the visibility.
You can further extend that method to put some default view in its place, or make something else visible.
You just need to change dynamically the maximum number of lines for the TextView you use in the row, for example:
textView.setMaxLines(Integer.MAX_VALUE);
Here is the function I created that I execute every time a row is clicked:
private void rowItemExpand(){
try {
//Get back the last textview touched
TextView textView = lastTouchedTextView;
boolean fullText;
if(textView.getTag() == null){
fullText = false;
}
else {
fullText = (Boolean) textView.getTag();
}
if(fullText){
textView.setMaxLines(mPrefs.getListViewMaxLines());
//Keep a flag to show the textview is opened
textView.setTag(false);
}
else{
textView.setMaxLines(Integer.MAX_VALUE);
textView.setTag(true);
}
}
catch(Exception e) {
Log.e(TAG,"rowItemExpand - Cannot get the selected index");
}
}
Finally I've used the following code (allows to have only one item opened):
private int openedItem;
...
#Override
protected void onCreate(Bundle savedInstanceState) {
openedItem = -1;
...
adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
#Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
int viewId = view.getId();
switch(viewId) {
case R.id.sms_body:
// override this to be able to handle open/closed listview items
// see also onListItemClick below
TextView textView = (TextView) view;
textView.setText(cursor.getString(columnIndex));
if (cursor.getPosition() == openedItem) {
textView.setMaxLines(Integer.MAX_VALUE);
} else {
textView.setMaxLines(2);
}
return true;
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
try {
TextView textView = (TextView) v.findViewById(R.id.sms_body);
if (openedItem == position) {
textView.setMaxLines(2);
openedItem = -1;
} else {
textView.setMaxLines(Integer.MAX_VALUE);
openedItem = position;
adapter.notifyDataSetChanged(); // call this to close all other opened rows
}
} catch (Exception e) {
Log.e(TAG, "Cannot get the selected index");
}
}
I have a custom listview with three items. One of them is like "Add this to the DB" and when I click to it it inserts something to the DB.
What I want it to do is after doing the insert, change the text to "Delete this from the DB" and also the onClick method to call a method to delete that record instead a method to insert.
Is this possible?
Here is my code:
final String[] opcs = new String[]{"Resultados", "ClasificaciĆ³n", text_fav};
ArrayAdapter<String> aa = new ArrayAdapter<String>(this, R.layout.list_menutipo_item, opcs);
m_list.setAdapter(aa);
m_list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent newActivity = null;
switch( position )
{
case 0: ...
case 2: if (isConnected(m_context))
{
aƱadirFavorito();
}
break;
}
}
});
It's definitely possible. The view parameter to the onItemClick callback is the view on which you clicked, you can simply change that view's content. i.e. view.setText("Delete this from the DB").
Also you will want to distinguish whether the next click is "Add this to the DB" or "Delete this from the DB", doing a string comparison here like if("Delete this from the DB".equals(view.getText())) might not be of good practice, you can set a flag in the view like view.setTag(true) to indicate that the current view's content is "Delete this from the DB". and later you can use view.getTag() to get back the flag to do the comparison.
Boolean flag = (Boolean)view.getTag();
if(flag == null || !flag) {
view.setText("Delete this from the DB");
flag = true;
//... code to insert a record to DB
} else {
view.setText("Insert this to the DB");
flag = false;
//... code to delete a record from DB
}
view.setTag(flag);
I'm facing some difficults when I try to use the performItemClick funcion of the ListView.
All I want to do is to perform a click programatically in the first item of the list.
How can I do that? I looked up that function in the documentation, but I didn't really understand its parameters.
I tried something like:
myListView.performItemClick(myListView.getChildAt(0), 0, myListView.getChildAt(0).getId());
But it didn't work (myListView.getChildAt(0) returns null)
Thank you in advance!
mList.performItemClick(
mList.getAdapter().getView(mActivePosition, null, null),
mActivePosition,
mList.getAdapter().getItemId(mActivePosition));
Where mActivePosition is your click position!
All the best! :)
This worked for me.
listView.performItemClick(
listView.getAdapter().getView(position, null, null), position, position);
use the adapter to get the view for the position of the item. The other 2 parameters I didn't want so I left them null. Leaving convertView null causes the adapter to render a new view. It's a performance issue but since this is only happening once in a while it wont have much effect. I don't need to specify the parent for anything because I'm not using it.
position is just the spot where your item is located.
Additionally these 2 lines of code before your performItemClick create the illusion of having the list item selected. They also ensure the appropriate item is on the screen.
listView.requestFocusFromTouch();
listView.setSelection(position);
This works best for me. Run this on the main thread.
new Handler().post(new Runnable() {
#Override
public void run() {
mList.performItemClick(
mList.getChildAt(mActivePosition),
mActivePosition,
mList.getAdapter().getItemId(mActivePosition));
}
});
This is similar to Arun Jose's answer, but it will queue a message to the main thread to give the ListView some time to initiate.
I tried the code below and it worked.
getListView().performItemClick(null, 0, getListAdapter().getItemId(0));
The first parameter (view) can be null.
I went with
listView.getAdapter().getView(position, null, null).performClick();
When using Listview (simple array adapter or custom adapter) define listview and other finally make perform click.
For example:
//At onCreate function:
lv = (ListView) findViewById(R.id.listView);
lv.setAdapter(new CustomAdapter(List_item.this, list, images));
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// on click function works
}
}
int position = 0;
lv.performItemClick(lv.getAdapter().getView(position, null, null), position, lv.getAdapter().getItemId(position));
Note: After creating the setOnItemClickListener only you should call
perform click. Otherwise, it will not correctly.
this may be old but this may help :
lvList.performItemClick(null, index, lvList.getItemIdAtPosition(index) );
NOTE : the first param is null and will still work, if you have a custom adapter, convertView will be filled with custom layout and view and such.
-cheers / happy codings.
mList.performItemClick(
mList.getChildAt(mActivePosition),
mActivePosition,
mList.getAdapter().getItemId(mActivePosition));
where mActivePosition is the position of the child view in List View.
Using the code #sulal proposed, you may place it in onLoadFinished, if you use a LoaderManager. Eg something like
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
//....
// mSelectedId keeps the currently selected id
// INVID is an invalid value
if (mSelectedId == INVID) { // nothing selected
// sulal's code
new Handler().post(new Runnable() {
#Override
public void run() {
mList.performItemClick(
mList.getChildAt(mActivePosition),
mActivePosition,
mList.getAdapter().getItemId(mActivePosition));
mSelectedId = mList.getAdapter().getItemId(mActivePosition);
}
});
}
mActivePosition may be 0 (ie position on the first item) or a position kept during eg onPause
At Firstly I tried to use this code in my Fragment(Master/Detail -> NameListFragment)
getListView().performItemClick(null, 0, getListView().getAdapter().getItemId(0));
But it didn't work. When I did #Override onStart() method in fragment and I moved my code to onStart(). After that it works properly for me.
If you are working on a unit test case.
Try to use getInstrumentation().waitForIdleSync(), to wait the list be loaded, and extend the ActivityInstrumentationTestCase2
See this answer.
I just meet this freak problem today , and I try me best to deal with it.
My condition is , when I first init the layout , I need make some item checked.
But when I use gridView.getChildAt(position) , always return null. I met this problem before , caused by Not finishing drawing layout . So I send a post message . handler.postDelayed( .. , ..) , It works. Thanks who motion this Exception.
This work for me
If you would get weird result when using getView, this is because the list item you want does not exist within visible parts. Use below:
private View getViewFromAdapterByPosition(int position, ListView listView)
{
View view;
int firstVisiblePos = listView.getFirstVisiblePosition();
int lastVisiblePos = listView.getLastVisiblePosition();
if (position < firstVisiblePos || position > lastVisiblePos) {
view = listView.getAdapter().getView(position, null, listView);
} else {
view = listView.getChildAt(position - firstVisiblePos);
}
return view;
}
And then,
listView.performItemClick(getViewFromAdapterByPosition(index, listView), index, 0);
Try this one:
public static boolean performClicKOnLisViewFromIndex(ListView listView, int index){
if(listView != null){
if(listView.getAdapter()!= null && listView.getAdapter().getCount() >0 && listView.getAdapter().getCount() > index ){
listView.performItemClick(
listView.getAdapter().getView(index, null, null),
index, listView.getItemIdAtPosition(index));
return true;
}
}
return false;
}
myListView.getChildAt(0) returns null because used this very soon.
use a delay for it.
or use below code:
private class MyAdapter extends BaseAdapter
{
private final Context context;
private HashMap<Integer, View> views;
public MyAdapter(Context context)
{
this.context = context;
views = new HashMap<>();
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
if(convertView == null)
{
if(views.get(position) == null)
{
final LayoutInflater layoutInflater = LayoutInflater.from(context);
convertView = layoutInflater.inflate(R.layout.my_grid, null, false);
views.put(position, convertView);
}
else
convertView = views.get(position);
}
TextView tv = convertView.findViewById(R.id.langView);
tv.setText(languageList.get(position));
return convertView;
}
}
and
adapter = new MyAdapter(getActivity());
myListView.setAdapter(adapter);
Runnable r = new Runnable()
{
#Override
public void run()
{
myListView.performItemClick(adapter.getView(position, null, myListView), position, 0);
}
};
myListView.postDelayed(r, 100);
just should use performItemClick() and it's okay.
listView.performItemClick(listView.getAdapter().getView(listView.getSelectedItemId, null, null), listView.getSelectedItemId, listView.getAdapter().getItemId(listView.getSelectedItemId));
In my case, none of the options solved my problem, so I made an adaptation in my CursorAdapter class.
I defined a global variable in the scope, so I just call the class changing this value and check the cursor position by passing the position value
mProductsAdapter.currentPosition = requiredPosition
in my ProductsAdapter builder
var currentPosition = 0
in bindView I do the check
if (cursor.position == currentPosition) {
// perform action
}
The performClick is probably called before listview was filled, put breakpoint in getView and on performItemClick and check wich is called first
getListView().performItemClick(null, 0, 0) did the trick for me (for position 0).
Dropping Some Experience.
using listview1.performItemClick, will also trigger your listview1.OnItemClickListener if you are using the listener with same listview in your code.
Hope It helps
If you would get weird result when using getView, this is because the list item you want does not exist within visible parts. Use below:
private View getViewFromAdapterByPosition(int position, ListView listView)
{
View view;
int firstVisiblePos = listView.getFirstVisiblePosition();
int lastVisiblePos = listView.getLastVisiblePosition();
if (position < firstVisiblePos || position > lastVisiblePos) {
view = listView.getAdapter().getView(position, null, listView);
} else {
view = listView.getChildAt(position - firstVisiblePos);
}
return view;
}
And then,
listView.performItemClick(getViewFromAdapterByPosition(index, listView), index, 0);
This works for me:
listview.getSelectedView().performClick();
This worked for me:
listView.getAdapter().getView(1, null, null).performClick();
This is from Begining Android Games. It creates a simple list of items which you can click to open a new activity. Each list item of course, would have to also be added to the AndroidManifest.xml as a separate activity with a .ListItem# name.
public class MainActivity extends ListActivity {
String tests[] = { "ListItem1",
"ListItem2",
"ListItem3",
"ListItem4"};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, tests));
}
#Override
protected void onListItemClick(ListView list, View view, int position, long id) {
super.onListItemClick(list, view, position, id);
String testName = tests[position];
try {
Class<?> classInstance = Class.forName("your.package.name." + testName);
Intent intent = new Intent(this, classInstance);
startActivity(intent);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}