Keyboard navigation in listview having multiple focusable element - android

I have a Android ListView which can have contains different types of listItem.
Some of the listitems have multiple focusable element themselves.
I am looking for a way to be able to navigate list using hardware keyboard as well as be able to select focusable elements inside listitem and navigate among them.
For example in below image all of the listItem have multiple buttons. So when I open my Activity, I should be able to navigate through listitem using keyboard up and down arrow.
But when I press Enter ( or D-PAD), then focus should go to first button inside that listItem. After that I should be able to navigate through all buttons using arrow keys
I am able to achieve first case when I set focusable false for all the buttons and set listView.setItemsCanFocus(false) on listView itself.
I have tried setting the setFocusable(false) before returning the view from adapter and then handling them in list OnItemClickListener
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
View v = listView.getChildAt(position);
v.setFocusable(true);
v.requestFocus();
Button b1 = (Button)(listView.getChildAt(position).findViewById(R.id.butt1));
Button b2 = (Button)(listView.getChildAt(position).findViewById(R.id.butt1));
b1.setFocusable(true);
b2.setFocusable(true);
b1.requestFocus();
}
});
But It is also not giving focus to button.

Related

ListView row is not clickable after adding button to the row

Currently, I have a ListView row. Clicking any area on the row, will yield ListView click events.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
this.getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
this.getListView().setMultiChoiceModeListener(new ModeCallback());
this.getListView().setOnItemClickListener(new ListViewOnItemClickListener());
} else {
// http://stackoverflow.com/questions/9754170/listview-selection-remains-persistent-after-exiting-choice-mode
this.getListView().setOnItemLongClickListener(new ListViewOnItemLongClickListener());
this.getListView().setOnItemClickListener(new ListViewOnItemClickListener());
}
Now, for each row, I would like to add a small button. Clicking on the small button will yield button click event, which is different from ListView original click event.
In my ArrayAdapter, I use to have
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = activity.getLayoutInflater();
rowView = inflater.inflate(R.layout.watchlist_row_layout, null);
...
}
Button button = (Button)rowView.findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Utils.showLongToast("BUTTON CLICK");
}
});
Clicking on the button will yield button click event. However, clicking on area other than button, will not yield any ListView click event anymore.
May I know why is it so? Is there any way to resolve this?
If you want to make both Rows and Buttons clickable, set
android:focusable="false"
for your Button. The same goes for ImageButtons, RadioButtons, ...
Android has been primarily designed for a large set of input methods.
The entire system is completely capable of working with no touch
screen. To navigate through the UI, the user can use a directional pad
which focuses Views after Views if and only if those Views are
focusable. By default, all Android controls are focusable. In order to
prevent having controls that are not focus-reachable, the ListView
will simply prevent the selection (and click) of an itemview. By
design, the ListView blocks clicks of itemview containing at least one
focusable descendant but it doesn’t make the content focus-reachable
calling setItemsCanFocus(true).
Here is the whole great explaination: Having several clickable areas in a ListView
It's worth noting that the preferred way (even according to the link provided in the accepted answer) is to set the android:descendantFocusability attribute to block focus from the root layout you're inflating within the adapter. There can be potential situations where simply setting the focusable attribute to false on an individual element won't solve the problem, but the descendantFocusability attribute will.

add buttons at the end of selected listview item in android dynamically?

I have a listview in which my list contain textview,means I have a list of text where user can select the text, read it and set margin note at the end of that text and a button is created over there. So when next time the user read that text then the button/buttons is there and when click on that button a popup is open where he can see his margin note.
Now the problem is that he can create more than one margin note at the end. In this case I have to create one or more button dynamically at the end of that selected textview. So please help me I am unable to create more than one button dynamically.
There are a couple of ways to do it.
1) Create the buttons (max the user will require) already in the xml file of the list item element and set their visibility to invisible or gone. When the user selects it you can set the visibility to visible. The visibility can be set dynamically.
2) The other way is to add buttons programatically. List views do reuse views for performance purposes. this could explain as to why you are having trouble with the button moving positions. in this case you have identify the id of the list item and add and remove buttons every time the view is created in your getView method of your list adapter.
Remember to chk the condition on your getView method and set visibility or add/remove button.
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> list, View v, int pos, long id) {
System.out.println("I clicked row item");
button1= (Button)v.findViewById(R.id.button1);
button1.setVisibility(button1.isShown() ? View.GONE : View.VISIBLE);}

Update ListView item's drawable state when child clicked

The problem:
I have a ListView item with a relatively complex layout. One of the children in the list item view is a TextView with links. The TextView can handle the clicks on links found in it(by using Linkify), and has a OnClickListener that handles click on parts of the text that are not links. The listener will just get the position of the view in the ListView and perform a click:
#Override
public void onClick(View v) {
int position = mListView.getPositionForView(v);
mListView.performItemClick(v, position, mAdapter.getItemId(position));
}
Everything works fine, except the click doesn't trigger the ListView to update the list item's drawable state. It does trigger that when you click on other TextViews in the item that are not clickable.
Thanks!
Got it working.
Set the list item view clickable and set its background as a state-list drawable, also set addStatesFromChildren to true. This will make sure the state of the list view item is changed when any of its children is clicked(assume the child is clickable).
However, this will cause the ListView itself not receiving focus, so you need to handle the click by adding View.OnClickListener to the list item itself instead of adding a OnItemClickedListener to the ListView.

Android - OnItemClickListener listview

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 ;)

Minimum scroll amount when programmatically selecting ListItem in android ListView

refering to this question: how does scrolling in android listview work?
on change from state 2 to 3 the clicked listitem is increased in its size to show more information. if the clicked item was the last one on screen, the extended listitem is not fully visible because the new content flows out at the bottom of the screen.
my current solution is to call "setSelection(index)", if the last visible listitem was clicked. this results in a state were the selection is brought to the top of the screen. this is annoying because the listitem moves from bottom to top.
is there a way to avoid this? this means, is there something to let the listview know, that is should scroll only the minimum amount of pixels, so that the clickeditem is fully visible?
or have i to programm this functionality on my own?
Add a custom OnItemClickListener to the ListView. Implement OnItemClickListener.onItemClick like this:
public void onItemClick(final AdapterView<?> parent, final View view,
int position, long id) {
View hiddenContent = view.findViewById(R.id.hiddenContent);
hiddenContent.setVisibility(View.VISIBLE);
// At this point the layout hasn't be redone and you don't have reliable
// measurements on the view. It would be nice to do something after the view
// has gone through another layout
view.post(new Runnable() {
public void run() {
Rect r = new Rect();
view.getDrawingRect(r);
parent.requestChildRectangleOnScreen(view, r, false);
}
});
}
Whenever you click on a list item to show the hidden content the ListView control will go ahead and do whatever scrolling is needed (or no scrolling if none is needed) to completely show the row.

Categories

Resources