I have a ListActivity; and for each item in the ListView there is a checkbox.
When you touch a list item, another Activity launches.
When you use the trackpad/trackball to highlight (read: select) an item and click the trackpad, it essentially simulates touching the item. This causes my other Activity to launch.
I would like clicking the trackpad to check the checkbox of the highlighted item. Is there a handler I can override to do this?
You need to override the onTrackballEvent(MotionEvent) method and catch ACTION_DOWN. Here is an example of how to do this:
#Override
public boolean onTrackballEvent(MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
//Do your work here
return true;
}
return super.onTrackballEvent(event);
}
Hope this works for you!
Not sure on a definite answer to this, but one thing worth researching is android:focusable.
I think your best bet is to make the List Items themselves not focusable, but the checkboxes focusable. This way when the user scrolls with the trackball/pad it will switch focus between the checkboxes instead of the list items, and behave in the way you want. This won't affect touch events.
Related
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.
I am trying to cope with one (seemed to be) smalll thing. In my app I've got one activity with two EditText fields.
I want one of them to be normall field (etNormal), and the other (etButton) behave more like button, so when you touch it, the keybord is not shown but instead the sliding drawer is opened. If sliding drawer is opened and you will press the normall edittext sliding drawer will hide.
I've tried adding OnClickListener and OnTouchListener (not in same tries) to both with condition if etButton was clicked/touched open sliding drawer, if not then close.
The outcome was strange. When it was OnTouchListener test it was more like toggle, so when I pressed one drawer opens and on another close. When it came to OnClickListener I needed to press each edtitext twice to get action done.
And to hide keybord in etButton I am using setInputType(InputType.TYPE_NULL);. I've tried also setEnabled(false); but then I was even unable to click/touch it. The one defect of currently used method is when I am changing click from etNormal to etButton, the keyboard is still shown and it doesn't hide.
So, can anyone tell me what I can do to achive my goal?
EDIT:
I've erad your current suggestions and modified a little my code, but still it is not working.
This is a part of it where I am assigning OnTouchListener:
OnTouchListener touchListener = new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent ev) {
if(v==etButton && ev.getAction()==MotionEvent.ACTION_DOWN) {
slidingDrawer.animateOpen();
}else {
slidingDrawer.animateClose();
}
return false;
}
};
etNormal1.setOnTouchListener(touchListener);
etNormal2.setOnTouchListener(touchListener);
etButton.setOnTouchListener(touchListener);
Also in etButton declaration in XML layout file I have:
android:focusable="false"
But now, on etButton touch nothing hapens (only sliding drawer hides if was opened), and when etNormal1 or 2 is touched sliding drawer shows up or hides depending what was first (in other words toggel).
Any idea, what is wrong here?
Got an editText working like that with
android:focusable="false"
android:clickable="true"
Then an OnClickListener to override the action
In addition to above answers, I hide cursor using cursorVisibility!
android:focusable="false"
android:clickable="true"
android:cursorVisible="false"
android:focusableInTouchMode="false"
cursorVisible To show/hide the cursor on clicking the EditText
focusable To gain focus when user is touching the view, like EditText
focusableInTouchMode To keep a view selected. (select and click are different)
For detailed understanding, refer here
In your layout, add the following attribute to the EditText
android:focusable="false"
android:focusableInTouchMode="false"
Next, write method to handle the click on the EditText and add your application logic .
If you are using onTouch event, when you click the edittext, you will get two events with action as MotionEvent.Action_down and action Up. so basically it will give the effect of clicking the edit text twice. can you please provide the code so that we can have a deep look.
ReWrite your code as :
OnTouchListener touchListener = new OnTouchListener() {
boolean isOpen=false;
#Override
public boolean onTouch(View v, MotionEvent ev) {
if(v==etButton && ev.getAction()==MotionEvent.ACTION_UP) {
if(!isOpen){
slidingDrawer.animateOpen();
}else{
slidingDrawer.animateClose();
}
isOpen=!isOpen;
}
return false;
}
};
If etButton needs to be an EditText (why not a button, if it should behave like one?), maybe you could set an onFocusChangeListener. Once it gets the focus, you can show the drawer...?
Not sure about not showing the keyboard...
EditTexts are tricky. The reason why you have to press twice when you have use an OnClickListener is that the first time around the EditText gets focus and this consumes the touch event, in that case the OnFocusListener is triggered. When you touch the second time, the EditText already has Focus so now a click event is triggered.
I would suggest you try to do this without EditTexts. That would in any case yield a cleaner and simpler solution. Why exactly do you want to use EditTexts instead of Buttons?
I have implemented swipe behavior in my list view. So, basically, you can drag a item and item's alpha value would change accordingly (thanks to code by Roman Nurik Roman Nurik & Tim Roes). The application is doing fine. Basically, on a generic list item, touch is treated as click, so for list without dragging facility, do not find difference between the two. But in my case, since I detect the co-ordinate at onTouch() to judge whether the user is scrolling left to right or right to left. My list does makes a difference between touch and click. So, I want to know do I dispatch a click event manually on list item so that even if user has not clicked and has dragged the item on touch, i still get to call OnListItemClick().
Thanks.
Long time, no reply given.
Anyway, I thought to share my own findings on this question.
I found that there is no way of dispataching an event manually as far as I know. But I found that I could handle my problem in another way. Here is how I handled it.
public boolean onTouch(View v, MotionEvent event) {
if(v.isPressed()
//
}
isPressed() would return when view is in pressed state. When it returns true, you can proceed further.
Hope it helps someone else.
I have an expandable list with all groups always expanded and the groups not collapsable. The problem is that even if I made the groups to not collapse when I click on them the "select" effect is still visible and I don't want it to be visible. How can I do that?
Any answer would be appreciated.
Thanks
I have figure out myself after all how to do that :D I have put this code:
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
return true;
}
});
in the adapter of the ExpandableList in the getGroupView method. And now it's working.
Normally when you click on the group name, it collapses automatically. Here is an example of expandableListView. Moreover, I could hardly make any comment unless I see what you did.
I have a listview that shows a list of views for every row/Item (A list item can have for example 2 or 3 buttons). All Items are set to do not be focusable and not be clickable. This way clicks on the items call to my ListView OnClick. What I want to do now is call performClick() on the real clicked view (that did nothing because it was set as not focusasble/cickable). Is this possible? I have tried to find a method to get a view based on a click location and did not find anything and on the other hand onItemClick click handler for a list view seems not to get the x/y of the touch either. I know that for this I could use OnTouchEvent but then I won't be able to know what item was clicked, etc...
okay try this, might help you... set a common onClick for buttons as well as the ListItem.
#override
public void onClick(View v) {
Sting position=v.getTag().toString(); //<--- like this
//task to do when clicks on the view...
switch (v.getId()) {
case R.id.<id_of_the_button1>:
//task to do when clicks on the button 1
break;
case R.id.<id_of_the_button2>:
//task to do when clicks on the button 2
break;
}
implement OnClickListener in the custom adapter and over ride it with the above onClick.