I want to have one ListView that when I click on the item the view slide out to the left.
So I have:
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
arg1.startAnimation(openAnimation);
}
});
However, animation applied to the different item in the list instead of the one being clicked on. The behavior seems to be random as sometime it happened to more than one item at the same time.
As I suspected this is because of the way Adapter reuse it's view to create item. I went to modify the getView method in my Adapter to inflate new view every time it's being called. Then the animation doesn't happen any more.
Is there a way to resolve this? I tried to move the animation to inside my Adapter but then I can not associate it with other action on the Listview.
Ultimately, I want the item to be clickable but when swipe left/right reveal delete button (iOS delete behavior). Am I on the wrong track here? This should be possible though as Android can implement swipe to remove in the Notification bar.
I recommend that you check this thread also.
I don't think, that this is possible without having to modify your adapter to suit this type of behavior. For what I understand, you don't have any problems with implementing the code recognizing the swipe gestures on different ListView-rows, only with the animation the should follow this gesture on according row(s).
I'd rewrite the adapter to suit at least 2 row types: normal rows, and rows to be deleted. In the "getView()" method of your adapter, you should only reuse the convertView of normal Views. Rows that are to be deleted should not reuse them, so that animating one would not modify the others.
Upon clicking a normal row, you should first tell the adapter that the row on the clicked position is now of type to-be-deleted, call .notifyDatasetChanged(), and then start the animation on that row.
Related
I have a question about some behavior in an AdapterView.OnItemClickListener that has me a bit flummoxed.
I have a ListView backed by a custom CursorAdapter. The Cursor is being managed by a LoaderManager. The ListView also has an OnItemClickListener. The data loads properly and the ListView is correctly populated - in this case with many items.
What I'm finding is that the position argument to onItemClick is 0-based relative to the items showing on the screen, not the entire list. So for example if I scroll down and select the first viewable item, I'll actually get the first item in the list (which is not visible) instead of the one I selected. When I use a debugger, I see that position actually has a value of 0 even though the item selected was much further down in the list.
What's odd is that this worked fine until I started using the LoaderManager.
I'm using the v4 support library.
If I do something like this:
public void onItemClick( AdapterView<?> parent, View listItem, int position, long id ) {
Cursor c = myListAdapter.getItem( parent.getFirstVisiblePosition() + position );
// do stuff
Then I get the data I actually selected, but I somehow feel this is wrong. I shouldn't have to use getFirstVisiblePosition().
Any ideas?
Thanks
I guess you might be using the convertView parameter of the getView() method to recycle the views. Using this might be causing the issues here. Kindly try using an alternative and check whether the issue still exists or not
I have a ListView with a custom adapter, displaying information from a database.
When I start the app, the data is read from the database, given to the adapter, which is then attached to the ListView. A LayoutAnimationController is run on the ListView, displaying the contents smoothly.
this._lvList = (ListView)_v.findViewById(R.id.lvList);
this._lvList.setAdapter(new TableAdapter(getActivity(),R.layout.tablerow,Category.getCategories()));
LayoutAnimationController lac = new LayoutAnimationController(AnimationUtils.loadAnimation(getActivity(), R.anim.slide_in_left));
lac.setDelay(0.2f);
this._lvList.setLayoutAnimation(lac);
this._lvList.startLayoutAnimation();
No problem at all.
Now when I click on any entry of the ListView, the entries which were not clicked disappear, the clicked entry becomes the one and only entry in the list and is displayed at the top, as expected.
View v;
for(int i = 0;i<_lvList.getChildCount();i++) {
v = this._lvList.getChildAt(i);
if(v!=clickedView) {
Animation animSlideOut = AnimationUtils.loadAnimation(getActivity(), i%2==0?R.anim.slide_out_left:R.anim.slide_out_right);
animSlideOut.setStartOffset(i*50);
// some more stuff
}
v.startAnimation(animSlideOut);
}
This works as well, but now the problem, if I click again on that single list entry, I want the list to repopulate, displaying all items again.
I thought I could use the code from the start (the first snippet), as it works fine when starting the app, but...this time...it doesn't. No animation happening. The reason is, there are no views to animate in my ListView (except the one from the previous step).
Instead of creating a new Tableadapter I already tried to clear it, fill it new, called notifyDataSetChanged()... no use, as
_lvList.getChildCount();
stills returns 1 view, while the adapter holds all 18 entries.
I as well tried
requestLayout();
forceLayout();
invalidate();
invalidateViews();
to force the ListView to generate its child views before the animation, but it's not working. So atm the ListView just appears instantly, somewhen after my call to the layout animation.
Summary : my ListView contains no child views before the start of the layout animation, how can I force it to generate them?
Thx in advance :)
Hmm... have you done this yet? (below)
in your custom adapter, override the method:
#Override
public View getView(int position, View convertView, ViewGroup parent){
//the position of the item, the convertView is the view layout of what that row is
}
to change how the listview is updated. this getView method gets called by Android every once a while to refresh the view (you don't call it manually)
also, i think you only need to call
listView.notifiyDataSetChanged() and listView.invalidate() to force the update, after you repopulate the list
you can read more on listviews here:
http://www.vogella.com/articles/AndroidListView/article.html
http://developer.android.com/guide/topics/ui/layout/listview.html
I developd a viewpager with custom list views in android. I followed the tutorial View Pager Part 1-3. The major difference in my development is that i used a customlistview in the views of the paager. The list items in the listview also support click events to display more info about an item.
Here is the problem; I handled the onItemClick inside the instantiateItem method but i noticed that when an item is clicked, the content displayed is that of the adjacent listview (i.e if item 2 of page 2 is clicked the info displayed is item 2 of page 3).
I realised this happens because the pager loads adjacent lists so as to make rendering faster for the user so my code uses the preloaded list instead of the list in current display.
I thought to find out the appropriate way to handle listview click events in viewpager, code snippets, links,.. will really be of help. The appropriate method to use to handle the click events.
Thank you
You have to get it from the adapter of the listview (the first parameter of the onItemClick method):
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
// NOT THIS!: mValue = (HereYourClass) listView.getItemAtPosition(position);
mValue = (HereYourClass)a.getAdapter().getItem(position);
}
Here's what I want to do:
I have this list of tasks. When I click on one of the items I want this to appear:
Assuming that menubar can be found with
findViewById(R.id.menubar);
Can someone please tell what code I have to put onItemClickListener
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
NOTE: The menubar visibility its set as GONE.
Thanks!
Without looking at the code, a precise answer is not possible. However, when I first wanted to implement a "Quick Action Bar" similar to the one you have shown, I had followed this example here:
http://code.google.com/p/simple-quickactions/
And this with some styling put in: https://github.com/lorensiuswlt/NewQuickAction3D
Hope this helps....
It is a bit difficult without seeing any code, but I can give you some logic ideas.
Based on your description, I'm assuming that those quick bar controls are hidden on EACH listview item so, it goes:
Fotos (visible)
Action Controls (hidden)
[End of Item]
PROJECTOS (visible)
Action Controls (hidden)
...
I think the OnItemClick method gives you the view (item: Fotos, Projectos, etc) that was clicked as the 2nd argument. If you cast that back to whatever layout you used to create the listview items, you should be able to use findViewByID to get access to the hidden controls that are on each listview and make them visible.
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
//Assuming each item is a linear layout
LinearLayout itemAsLL = (LinearLayout)view;
//find the action bar controls
LinearLayout actionControlsLayout = itemAsLL.findViewById(R.name.of.actioncontrols.id);
//Make it visible
actionControlsLayout.setVisibility(VIEW.Visible);
}
You would need to find a way to hide those controls when another item is clicked? Maybe save the view (or position in the adapterView ) as a class variable and when another item is clicked, go to that view/find that view and hide the controls.
I finally found out the answer. Apparently, when you fill a view with lots of tasks, the adapter does not fill everything when you load the layout, so everytime you scroll down, hes putting more items on the listview.
What you have to do is make sure you put a field "loaded" and, in case is false, it does not show the menubar below that item, otherwise, when you click in one of the items of that list, when you scroll down, since they will have the same relative position (if you click on the first item, the position = 0, when you scroll down, there will be another position = 0) the menubar will appear on both items.
Hope it helps ;)
I'm currently making a SMS Application in Android, the following is a code snippet from Inbox Listactivity, I have requested a cursor from the contentresolver and used a custom adapter to add custom views into the list.
Now, in the custom view i've got 2 TextViews (tvFullBody,tvBody)...
tvFullBody contains the Full SMS Text while tvBody contains a short preview (35 characters)
The tvFullBody Visibility is by default set to GONE.
My idea is, when the user clicks on a list item, the tvBody should dissappear(GONE) and the tvFullBody should become visible (VISIBLE). On Clicking again, it should revert back to its original state.
//isExpanded is a BitSet of the size = no of list items...keeps track of which items are expanded and which are not
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
if(isExpanded.get(position))
{
v.findViewById(R.id.tvFullBody).setVisibility(View.GONE);
v.findViewById(R.id.tvBody).setVisibility(View.VISIBLE);
}else
{
v.findViewById(R.id.tvFullBody).setVisibility(View.VISIBLE);
v.findViewById(R.id.tvBody).setVisibility(View.GONE);
}
isExpanded.flip(position);
super.onListItemClick(l, v, position, id);
}
The Code works as it is supposed to :) except for an undesired sideeffect....
Every 10th (or so) List Item also gets "toggled".
eg. If i Expand the 1st, then the 11th, 21th list items are also expanded...Although they remain off screen, but on scrolling you get to see the undesired "expansion".
By my novice analysis, i'm guessing Listview keeps track of 10 list items that are currently visible, upon scrolling, it "reuses" those same variables, which is causing this problem...(i didn't check the android source code yet.)
I'd be gratefull for any suggestion, on how i should tackle this! :)
I'm open to alternative methods aswell....Thanks in advance! :)
Your diagnosis of the problem almost correct. What's happening is that Android is reusing the Views it creates to display the list to save memory. Instead of creating a new View for every item in your list, Android creates just enough to fill the screen, updating them to show the relevant data for the items which are currently visible.
So when you show tvFullBody when the user clicks on an item, when that View is re-used later tvFullBody is still visible.
You may have to write you own ListAdapter to make sure the Views are displayed how you want. It should be as simple as extending the ListAdapter you are currently using and overriding the getView() method to ensure that tvFullBody is hidden.