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!
Related
I basically want to do something when clicking a ListView where there is no item, so I don't want to use the ListView.ItemClick Event Handler. When I try to use ListView.Click it tells me that I have to use item click. Any help?
I tried Lucas's solution this way:
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/lvQueue"/>
<ListView.GestureRecognizers>
<TapGestureRecognizer
Tapped="OnTapGestureRecognizerTapped"
NumberOfTapsRequired="1"/>
</ListView.GestureRecognizers>
and also this way:
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/lvQueue">
<ListView.GestureRecognizers>
<TapGestureRecognizer
Tapped="OnTapGestureRecognizerTapped"
NumberOfTapsRequired="1"/>
</ListView.GestureRecognizers>
</ListView>
You could add TapGestureRecognizer on the ListView
in Xml
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/lvQueue"/>
in Code behind
ListView listView = FindViewById<ListView>(Resource.Id.lvQueue); ;
listView.SetOnTouchListener(new GestureListener());
public class GestureListener : Java.Lang.Object, View.IOnTouchListener
{
public bool OnTouch(View v, MotionEvent e)
{
// do something you want
return true;
}
}
Update
Because the touch event will always been invoked before item click action, so if you do want to only add click event on white space of the page when the items of ListView is few . We could define another View below the listview and set the click event as a workaround.
in xml
Put the ListView in a LinearLayout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_main">
<ListView
android:id="#+id/listView"
android:background="#android:color/holo_blue_light"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" // set the weight as 1 , so that it will warp the white space of the screen auto
android:background="#android:color/holo_blue_light" // set the background color the same with thelistview
android:id="#+id/view"/>
</LinearLayout>
in code behind
TextView view = FindViewById<TextView>(Resource.Id.view);
view.Click += View_Click;
private void View_Click(object sender, EventArgs e)
{
//...
}
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
I am using touch event on LinearLayout in which there is a list view(Its a child). When I touch on list view part touch event does not gets called. below is my code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/llFavourite"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/llProgressBar"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="false"
android:gravity="center"
android:visibility="gone" >
<ProgressBar
android:id="#+id/pbLoading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="Loading"
android:indeterminate="true"
android:progressDrawable="#android:drawable/progress_indeterminate_horizontal"
android:visibility="gone" />
</LinearLayout>
<ListView
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:cacheColorHint="#android:color/transparent"
android:listSelector="#android:color/transparent"
android:focusable="true">
</ListView>
</LinearLayout>
My animation:
final Animation slidedown = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_down_half);
llFavourite.setOnTouchListener(new OnSwipeTouchListener(MidnightMainActivity.this) {
#Override
public void onSwipeBottom() {
llFavourite.startAnimation(slidedown);
inflateFavouriteLayout(MODE_REFRESH);
}
});
but when I click on layout part event gets called. Is there any property which i should enable or disable?
Thanks in advance.
android:focusable="false"
android:focusableInTouchMode="false"
doesn't work for ImageButton.
In your layout xml, add this property to root layout
android:descendantFocusability="blocksDescendants"
from your calling class add
ListView lView = (ListView) findViewById(R.id.list);
lView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Log.i(position);
}
});
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.