I have an ExpandableListView with a group header that shall expand and collapse when clicked. This works for clicks on an ImageView that is inside the list item and it works on directly clicking the item and so on but it doesn't work for a TextView in the list item.
I have to give the TextView a OnClickListener and catch the click separately. This is not nice especially because I don't have all data that I normally get in the OnGroupClickListener.
I read about making the TextView clickable=true and focusable=false but this didn't help. What else will I have to set or change to make the click go "through" the TextView to the base view?
Edit
see my answer for the reason.
Anyway I show how the GroupClickListener is set.
And of course clickable is set to true, not false.
In my activity that displays this list I do this
ExpandableListView.OnGroupClickListener groupClickListener = new ...() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
if (parent.isGroupExpanded(groupPosition))
parent.collapseGroup(groupPosition);
else
parent.expandGroup(groupPosition, true);
return true;
}
};
then assign this to the expandable listview.
listView.setOnGroupClickListener(groupClickListener);
The solution is pretty clear now as I found it.
I did set android:inputType="textNoSuggestions" what I found as advice because I sometimes experienced the TextView to show underlines as an indicator of spelling mistakes.
Probably this sets the view in focusable mode which captures the click.
I have to find out what's the deal with those underlines. Why only sometimes? Why at all? They are pretty stupid for an element that shall not accept any input but simply display static text.
But at least I found it and I hope this can help others to save some time.
Related
I had a Listview with the following Adapter
SimpleAdapter simpleAdapter
= new SimpleAdapter(NewsListActivity.this,res,R.layout.newslist_adapter,new String[]{"title","description","link"},new int[]{R.id.title,R.id.description,R.id.url});
lView.setAdapter(simpleAdapter);
where lView is the ListView, and res is an HashMap.
In the ListView's onItemClick, I was able to get each View's Description TextView using the Code below
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
View v1 = lView.getChildAt(position - lView.getFirstVisiblePosition());
if(v1 != null){
TextView des = v1.findViewById(R.id.description);
Toast.makeText(getApplicationContext(),des.getText(),0).show(); // returns the Text at exact TextView Clicked
des.setBackgroundColor(R.color.red); //Here is the PROBLEM, It changes the Background Color of TextView I clicked on, but it ALSO changes some other TextView's background color
}
}
As I added in the Comments, The Toast message returns The exact Text in the TextView, but changing the background color also changes some other TextView in the ListView's color
I don't seem to Understand what I am doing wrong.
EDIT
I only posted the portion of the project , so as not mess up all the place with my source code.
It's an RSS feed reader project, but now I realize the problem is with all ListViews. Pleased kindly help with the link below
Android ListView getChild() not working properly
Ok, after months of confusion, pain of being self-taught and punishment of walking alone (no direct access to senior dev for help), I finally realized what I was missing.
The problem arise from ListView re-using view as some sort of memory management techniques (for performance purposes) or so. That's why in my case whenever the background color of a ListView Element is changed and the View is being recycled it affect the background color of whichever item that uses the Recycled view.
As for the fix, this this link should help
I basically want something similar to the Twitter or Pocket app where you long click on an item in the list View and it gives you a set of options to perform on that item by changing the layout of that item, to reveal a set of buttons.
ListView lv= getListView();
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> av, View v,
int pos, long id) {
// TODO Auto-generated method stub
Context ctx = getApplicationContext();
mDbHelper.deleteNotes(id);
fillData();
Toast.makeText(ctx, "Long Clicked at" + id, Toast.LENGTH_SHORT).show();
return false;
}
});
My long click code is here. Right know I just directly delete the item that is long clicked, but I want the user to see 3-4 buttons when an item is long clicked in place of the said item.
Anyone knows how to do it?
EDIT
Here is the twitter image:
What you could do, is when the user long presses, simply within your adapter, hide or show a, for example, LinearLayout containing all the buttons and so on within it.
Make sure this element you are showing fits itself below or above all other usual elements.
Do you get what I'm trying to say? Holla if you need more info.
Update 1
Okay so in reply to your comment, no you won't need to create a separate xml file etc. See this for example,
Your custom row xml with two layouts:
RelativeLayout mainView
RelativeLayout extraView
In your row xml have an extra layout (my preference is relative, it's upto you anyway), and set this layout to be below the main stuff (make sure they both fit on the row). So in this scenario, mainView is the layout with the stuff you always want shown and extraView is the stuff you want only when long pressed.
Make sure the default visibility setting for extraView is set as GONE
Then, simply when long pressed, that specific rows extraView.setVisibility(View.VISIBLE);
And obviously vice versa when no longer long pressed.
Hit me up if you're confused, and apologies for the non formatted reply as I'm currently commuting and replying via my mobile, will format the answer when at a pc.
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 have a list of items, which i'd like to "check" with filled star when user clicks on one item in the list.
I have a ListView with text & image, represented in XML layout, and using simple StringAdapter.
I've implemented the above by doing this:
this.listViewSub.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(final AdapterView parent, final View view, final int position,
final long id) {
ImageView img = (ImageView) view.findViewById(R.id.unchkImg);
img.setImageResource(R.drawable.starchk);
I guess its not the right way to do it, but i don't have any idea how else to code it.
This code for some reason changes few random items in the list, and after one click i have about 4-5 items with icon changed.
Any idea how to solve it correctly?
Thanks
It's hard to tell without code, but my first guess is that as the views get recycled, if you don't reset the ImageView to use the default "unchecked" image in the getView method, each time you star an item the view will remain starred, even it is used for a different item. So your adapter should just reset the ImageView's image resource ; though in that case, you'll have to remember which items you starred in order to reset the ImageView correctly : set it to do the default drawable or to the starred one.
At last, after long search - i've found the answer in an article:
http://www.codegod.biz/WebAppCodeGod/Android-ListView-with-dynamic-Images-AID588.aspx
That was a tough one.
I'm trying to put a checkbox into ExpandableListView. How do I do that? I extend BaseExpandableListAdapter and put the following into getGroupView():
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
ViewGroup parent) {
View view = convertView == null ?
context.getLayoutInflater().inflate(R.layout.onet_head, null) : convertView;
((TextView)view.findViewById(R.id.onetText)).setText(cats.get(groupPosition).value);
return view;
}
Notice that inflated layout? That's where I'm putting TextView and CheckBox.
I noticed that placing a checkbox into my group row layout disables default group row functionality when clicking on the row makes a secondary (child) list appear. CheckBox is functioning as expected but when I click outside of the it the
click is never detected by ether CheckBox or by OnGroupClickListener. I suspect that placing CheckBox into group row this way interferes with event detection/handling but thus far I'm not able to track it down
Can
someone help me to resolve this?
The CheckBox works fine though including detecting clicks when
clicking directly on the box
Anytime you place an item that is focusable in a list the list items no longer respond to clicks or anything like that. For every item you place in the list item that is focusable (buttons, checkboxes, etc), you need to set the android:focusable attribute to false.
I had a similar question and that was the answer for me.
Android custom ListView unable to click on items