Goal: If at least one ListView item is selected, fade in a button. Fade out the button if no items are selected.
Problem: It's working, but the ListView becomes unresponsive for 1 - 2 seconds after an item is selected. I.e. I am unable to select other items in the ListView.
If I remove the animateLayoutChanges attribute from the LinearLayout, the ListView remains responsive.
Here is the simplified layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:animateLayoutChanges="true">
<ListView
android:id="#+id/category_listview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
android:layout_marginRight="#dimen/activity_horizontal_margin"
android:layout_marginBottom="#dimen/activity_vertical_margin"
android:layout_weight="1"
android:background="#drawable/category_list_border"
android:choiceMode="multipleChoice"
android:divider="#color/material_grey_400"
android:dividerHeight="0.5dp"
android:padding="0.5dp" />
<Button
android:id="#+id/study_button"
android:visibility="gone"
style="?android:attr/borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:text="#string/study_now" />
</LinearLayout>
And here is the code which sets the visibility of the button:
itemListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View selectedView, int position, long rowId) {
Log.d(TAG, "List item selected");
if (itemListView.getCheckedItemCount() == 0) {
studyNowButton.setVisibility(View.GONE);
} else {
studyNowButton.setVisibility(View.VISIBLE);
}
}
});
This occurs in the onCreateView lifecycle method of a fragment if that is relevant.
You should remove animateLayoutChanges from layout XML file. It tries to apply the transition everytime you select a list item. You should apply the transition only when the first item is selected or all items are unselected.
You can try adding the transition programmatically using LayoutTransition
Change the View.GONE to View.INVISIBLE
Related
I am using a custom adapter for a ListView that displays a list of items that can be clicked and should change the text of an description TextView below the ListView. The description should display a descriptive text about the currently highlighted item.
In my Fragment containing the ListView and the TextView I used the following code to register an OnItemClickListener
Java Code:
mTextView = (TextView) myParentView.findViewById(R.id.fragment_select_option_desc_text_view);
mListView = (ListView) myParentView.findViewById(R.id.fragment_select_option_list_view);
mListView.setItemsCanFocus(false);
mListView.setAdapter(new MyItemAdapter(getActivity(), mItems));
mListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
int itemId = SelectStateFragment.this.mItems[position].getId();
String description = DataStore.get().getItemDescription(itemId);
SelectItemFragment.this.mTextView.setFocusable(true);
SelectItemFragment.this.mTextView.setText(Html.fromHtml(description));
SelectItemFragment.this.mSelectedPosition = position;
view.setSelected(true);
}
});
Fragment xml:
<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" >
<ListView
android:id="#+id/fragment_select_option_list_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#color/list_view_background" >
</ListView>
<ScrollView
android:id="#+id/fragment_select_option_scroll_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:stackFromBottom="true"
android:choiceMode="singleChoice"
android:fillViewport="false" >
<TextView
android:id="#+id/fragment_select_option_desc_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="3sp" />
</ScrollView>
</LinearLayout>
Item xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/selectable_item_text_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="3sp"
android:textColor="#android:color/black"
android:focusable="false"
android:focusableInTouchMode="false"
android:background="#drawable/selectable_item_background"/>
</RelativeLayout>
The problem is: after I click on an item, the text view content gets updated as intended. However, I don't see any visual highlight of the selected item in my list view. Only if I click on the same item a second time my selection becomes visible as the item gets highlighted. The strange thing is: If I comment out the line
SelectItemFragment.this.mTextView.setText(Html.fromHtml(description));
and therefore skip the update of the TextView, the selection immediately shows with the first click of an item.
Is there anything wrong with accessing other UI elements in an OnItemClickListener? Do I have to trigger some layout update after updating the TextView?
Update: Inserted Sweety's suggestions into my code, added XML code
Try to set all items inside your list view to non focusable.
final ListView list = (ListView) findViewById(R.id.list);
list.setItemsCanFocus(false);
Also, make sure that for items inside list item set focusable false
android:focusable="false"
android:focusableInTouchMode="false"
Also view.setFocusable(true) before setText.
I am trying to fire a event when a user click the delete icon in the list , But I could not able to do it.I am using a simple cursor adapter with setviewbinder to display items in the list.In the setviewBinder method I set the textview layout clicklistener to be null that's why, view is not clicked when a user click in the textview.When a user is swipe in the list immediately delete icon is appeared.I need to fire a click event in the deleteIcon.Currently, when a user is clicked the delete icon, the whole view is clickable.I need to achieve when a user is clicked the delete icon, need to fired the event, only in the delete icon.
public boolean setViewValue(final View view, final Cursor data, int columnIndex) {
LinearLayout layoutTaskView=(LinearLayout)view.findViewById(R.id.layoutTaskView),
layoutTaskDelete = (LinearLayout) view.findViewById(R.id.LayoutDeleteTask);
boolean crossed = Boolean.valueOf(data.getString(columnIndex));
if(crossed){
icon.setImageState(new int[] { android.R.attr.state_checked }, true);
text1.setPaintFlags(text1.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
text2.setPaintFlags(text2.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
layoutTaskView.setOnClickListener(null);
}
}
Layout Xml File
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<LinearLayout
android:id="#+id/layoutTaskView"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:padding="15dp" >
<TextView
android:id="#+id/taskTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:id="#+id/taskName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:paddingLeft="10dp"
android:text="TextView" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/LayoutDeleteTask"
android:clickable="false">
<ImageView
android:id="#android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:padding="15dp"
android:src="#drawable/checkmark" />
</LinearLayout>
</LinearLayout>
ListView xml
<com.myexample.CrossView
android:id="#+id/crossview"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</com.myexample.CrossView>
Adapter Code
String[] from = new String []
{
DatabaseHelper.COLUMN_CATEGORY,DatabaseHelper.COLUMN_TASKNAME,
DatabaseHelper.COLUMN_CROSSED};
int[] to = new int[] {R.id.taskTime,R.id.taskName, android.R.id.content};
adapter = new SimpleCursorAdapter(context, R.layout.layout_list_item, data, from, to, 0);
adapter.setViewBinder(new CrossBinder());
lv.setAdapter(adapter);
public void onItemClick(AdapterView<?> parent, View v, final int position, final long id) {
ImageView icon = (ImageView)v.findViewById(android.R.id.icon);
icon.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(v.getId() == android.R.id.icon){
}
}
}
You need to use android:descendantFocusability = "afterDescendants" parameter to root layout of list item. In your case, the root LinearLayout.
For more information check this link.
EDIT : remove android:clickable="false" from your LinearLayout containing ImageView. Put android:clickable="true" in ImageView. Moreover, you can use ImageButton instead ImageView.
P.S. I have suggested to use android:descendantFocusability in main parent LinearLayout.
Create custom adapter like that answer Custom adapter for a list of items that have multiple child items?
This answer give tutorial link to create custom dapters for listview.
I have a list view with two text view and a delete button on the right corner (hidden), each list item is scrollable and delete button appears when I scroll to the left. I was able to get the position in the list onclick of delete button but I am unable to remove that list row.
Layout looks like this.
<?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:orientation="vertical" >
<HorizontalScrollView
android:layout_width="match_parent"
android:scrollbars="none"
android:layout_height="match_parent"
android:focusable="false" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:orientation="horizontal" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayoutTeamInvitesListItem"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false"
android:onClick="onClickTeamInvitesListText"
android:orientation="vertical" >
<com.headsup.customviews.TextViewPlus
android:id="#+id/textViewListNameTeamInvites"
style="#style/text_view_list_item_style"
android:layout_marginTop="10dp"
android:focusable="false" >
</com.headsup.customviews.TextViewPlus>
<com.headsup.customviews.TextViewPlus
android:id="#+id/textViewListEmailTeamInvites"
style="#style/text_view_list_item_style"
android:layout_marginBottom="10dp"
android:focusable="false" >
</com.headsup.customviews.TextViewPlus>
</LinearLayout>
<Button
android:id="#+id/buttonListViewTeamInvite"
android:layout_width="#dimen/teams_invites_listview_button_width"
android:layout_height="match_parent"
android:background="#FFFF0000"
android:onClick="onClickTeamInvitesListButton"
android:text="#string/delete" >
</Button>
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
Now I have to remove the list row when I click on delete button so I have "onClickTeamInvitesListButton" and function calls the activity class where I am redirecting it to the fragment, so that I could access the list view.
The function in activity looks like this.
public void onClickTeamInvitesListButton(View view) {
fragmentTeamInvites.onClickTeamInvitesListButton(view);
}
Function in fragment is like this.
private static ListView listView;
private static MyListAdapter mListAdapter;
...
...
public void onClickDeleteButton(View view) {
int position = listView.getPositionForView(view);
listView.removeViewAt(position);
mListAdapter.notifyDataSetChanged();
}
Found the answer .. needed to change my list code to this.
public void onClickDeleteButton(View view) {
int position = listView.getPositionForView(view);
listDataModel.remove(position);
mListAdapter.notifyDataSetChanged();
}
The problem is this:
public void onClickDeleteButton(View view) {
int position = listView.getPositionForView(view);
listView.removeViewAt(position);
mListAdapter.notifyDataSetChanged();
}
You are removing the item from the ListView, not from the datasource (the adapter). So, when you call notifyDataSetChanged() the adapter attempts to refresh the data, but since nothing has changed in the data, it displays all rows again.
You should remove the item from your adapter, not from the ListView!
I have a GridView in my app with the following item layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#android:drawable/list_selector_background" >
<TextView
android:id="#+id/notizenTitel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Titel"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold" />
<TextView
android:id="#+id/notizenBeschreibung"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Beschreibung" />
</LinearLayout>
Now I want to select an item if the user clicks on it. I tried with this code:
gv.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE);
gv.setOnItemClickListener(this);
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
GridView gv = (GridView) getView().findViewById(R.id.notizenGrid);
gv.setSelection(position);
adapter.notifyDataSetChanged();
}
But now if I click on an item the background is changed to yellow shortly and dissapead than. So the selector is working while I click on an item but not for the selection. Do you have any ideas why?
Add a property in linear layout
android:clickable = "true"
It will help.
If you add andrid:clickable="true", your gridView will not preform click event, it will block all click events.
Actually i have a viewpager that holds a Imageview and a listview over it, So when i click on the Listview i need to hide the listview and the bottom bar to make the ImageView fullscreen for all the views in side the viewpager. And onclick of the image view get back the views. But my issues are:
I cant implement onClickListner on Listview, to make the whole view to handle the tap. Am forced to use the onItemclickListner and it only hides when you click on the item(which is not desired).
When i click Listview(which is inside Fragment) inside the pager it doesn't hide for all the views except for the currentview, But am able to hide the actionbar and the bottom bar(on the Fragment Activity).
a screen shot for reference:
How can i achieve this or this is there any better way that i can hide the views.
Here is my ListView in side a Fragment:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:cacheColorHint="#android:color/transparent"
android:divider="#android:color/transparent"
android:listSelector="#android:color/transparent"
android:scrollbars="none" />
</RelativeLayout>
Here's my Fragment Activity layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/detailLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/form" >
</android.support.v4.view.ViewPager>
<RelativeLayout
android:id="#+id/form"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:padding="2dp" >
<EditText
android:id="#+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/btnSend"
android:drawableRight="#drawable/edit_keyboard"
android:inputType="textMultiLine"
android:maxLines="3" />
<ImageButton
android:id="#+id/btnSend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="#drawable/send" />
</RelativeLayout>
</RelativeLayout>
Here am successful with the onitemclicklister to the ListView:
listComments.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
if (getSherlockActivity().getSupportActionBar().isShowing()) {
getSherlockActivity().getSupportActionBar().hide();
listComments.setVisibility(View.GONE);
form.setVisibility(View.GONE);
} else {
getSherlockActivity().getSupportActionBar().show();
listComments.setVisibility(View.VISIBLE);
form.setVisibility(View.VISIBLE);
}
}
});
imageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
getSherlockActivity().getSupportActionBar().show();
listComments.setVisibility(View.VISIBLE);
form.setVisibility(View.VISIBLE);
}
});
Could you set the clickable property for the listView and check ? Also, whenever you add a new edittext to the do you add it dynamically ? If so that would mean that the you are adding items to the listView dynamically. The listView would not know if you have clicked on an item of the view itself hence a callback would get registered when you click the item as that takes preference.