I have a ListFragment, to which I attach some headers(a WebView among other stuff) and footers. I understand that Android handles the onLongClick event of WebViews to show a CAB with copy/paste to/from Clipboard. This is perfectly fine for me, but my problem is that whenever I long click on WebView's content, to show the CAB, this view (header of ListView), automatically scrolls to the bottom of it.
This seems like it is a default action for a ListView item longClick, so my question is, how can I override this thing (of autoscrolling to the bottom of the longClicked item), without damaging other stuff (like for example: if I long click on an item that doesn't need the CAB with copy/paste to appear, than ListView should handle it as it already does). I tried Overriding the onItemLongClick method of the ListView to return false (so it will pass the returning further, but it doesn't necessarily seem to do what I'd like it to do, and it creates a strange bug).
Basicly (I think) if the item that user long clicks on contains a WebView, I need to dispatch the longClick event to the WebView, otherwise ListView should handle it.
LE: I tested out against a fresh small sample of a ListFragment with a long(larger than the screen) WebView as its header, and is seems like it doesn't autoscroll to the bottom of the Header on LongClick on WebView. That being said, I can't see what could I do to create such action. Any ideas would be much appreciated, maybe I`m mistakely overlooking some small thing.
You can attach an OnItemLongClickListener to your list. In it's callback you can check if the long clicked row is the webview by checking the position corresponds to it and return true for this case
after you've devined your listAdaper:e.g:
SimpleAdapter adapter = new SimpleAdapter(
this,
list,
R.layout.playlist_view,
new String[] {"fileName","path"},
new int[] {R.id.text1,R.id.text2}
);
setOnLongClickListener
setListAdapter(adapter);
ListView listView = getListView();
listView.setOnLongClickListener(new AdapterView.OnLongClickListener() {
#Override
//Ovverride onItemLongClick click here (requires API 20+)
P.S: In my project list is
ArrayList<HashMap<String,String>>
Example of override long click:
public abstract boolean onItemLongClick (AdapterView<?> parent, View view, int position, long id
{
Intent service=new Intent(YourClassName.this,ClassToNavigate.class);
service.putExtra("ElementPosition",position);
service.putExtra("SelectedFromList",true);
startService(service);
}
It took me a very long while to determine what was the problem to this issue, but finally I managed to do it.
this very line:
requestWindowFeature(Window.FEATURE_NO_TITLE);
in the Activity was messing up everything. Hope that this will help someone else to not lose so much time on it.
PS. It can be reproduced with
<item name="android:windowNoTitle">true</item>
in xml too.
Related
Currently I am trying to implement a ListFragment or ListView navigation system where a user clicks on an item in the listview which then transitions and replaces it with another listview.
So Container Activity A has a screen. You press a button and it replaces that container with a ListView. You then choose one of the items and it then replaces the screen with a new fragment Listview. This repeats until a user gets to the end of the line to the product itself.
The Amazon APP currently has this implemented for their Item Navigation.
I am just looking for ideas on how to start a design pattern to create an app like amazon.
Does anyone know how they execute this? I am having problems finding the correct key word search to find examples of this functionality. If anyone can help me lead to examples to mimic this design it would be helpful!
I am not sure what exactly you want to do but if you want to replace a listview with another listview on click of an item in listview, then you dont have to make it so complicated.
Have a listview in which you feed data from an array using an adapter. On list item click. Change the data array with new array in the adapter and notify the listview.
Something like this:
mListView = (ListView)findViewById(R.id.mylist);
mAdapter = new Adapter(this, mArray1);
mListView.setAdapter(mAdapter);
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
-----
mAdapter.setListData(mArray2);
mAdapter.notifyDataSetChanged();
This way it will work for you.
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
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 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.
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.