Custom icons in expandablelistview have distorted dimensions - android

I have an expandablelistview that needs to have custom arrows. I tried setting the groupIndicator to a selector like so:
<ExpandableListView
android:id="#+id/home_drawer_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:childDivider="#android:color/transparent"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:groupIndicator="#drawable/expandable_list_view_selector" />
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/arrow_down" android:state_expanded="true" />
<item android:drawable="#drawable/arrow_right" />
</selector>
However, for some reason this is distorting the dimensions of the arrows, see below:
Any idea why they're being distorted, and how to fix it?

It turns out that the issue was that I was setting padding on the TextView in the group header, which was then distorting the image. I found the whole default group header and custom indicator to be extremely cumbersome to work with, you can't really customize the row at all without distorting the image, so I ended up using a custom view for the group header instead.
Set the ExpandableListView's groupIndicator to #null:
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:groupIndicator="#null" />
Add a custom group header, in my case ListViewGroupHeader.axml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="#dimen/padding">
<ImageView
android:id="#+id/group_header_arrow"
android:src="#drawable/arrow_right"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="10dp" />
<TextView
android:id="#+id/group_header_title"
android:layout_toRightOf="#+id/group_header_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#color/black"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_centerVertical="true" />
</RelativeLayout>
Set the custom layout in your adapter's GetGroupView method, keying off of the isExpanded property for which image to show:
var layoutInflater = (LayoutInflater)ApplicationContext.Activity.GetSystemService (Context.LayoutInflaterService);
var view = layoutInflater.Inflate(Resource.Layout.ListViewGroupHeader, null);
var arrowImageView = view.FindViewById<ImageView> (Resource.Id.group_header_arrow);
var titleTextView = view.FindViewById<TextView> (Resource.Id.group_header_title);
arrowImageView.SetImageResource (isExpanded ? Resource.Drawable.arrow_down : Resource.Drawable.arrow_right);
titleTextView.Text = title;
if (isExpanded && colorExpandedBlue) {
arrowImageView.SetImageResource (Resource.Drawable.arrow_down_blue);
titleTextView.SetTextColor (ApplicationContext.Activity.Resources.GetColor (Resource.Color.standard_blue));
}
return view;

I did a simpler solution, not very elegant, but works. Used a layer list, positioning the drawable resource with padding on top and bottom, this results in a drawable with the expected proportion of my expandable list view. The amount of padding may be different to your view...
The icon I used was downloaded at https://material.io/icons/
Create two layer list drawable:
File ic_expand_more_expandable_list.xml in drawable:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="#drawable/ic_expand_less_white_24dp"
android:top="8dp"
android:bottom="8dp"
/>
</layer-list>
File ic_expand_more_expandable_list.xml in drawable:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="#drawable/ic_expand_more_white_24dp"
android:top="8dp"
android:bottom="8dp"
/>
</layer-list>
and use then as your state:
File group_arrow.xml in drawable:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/ic_expand_less_expandable_list"
android:state_expanded="true" />
<item android:drawable="#drawable/ic_expand_more_expandable_list" />
</selector>
And then add it as the group indicator of the ExpandableListView
android:groupIndicator="#drawable/group_arrow"
It is working perfectly here in all tested resolutions.

Related

Android Recycler View Ripple Effect not working

I am using the following xml drawable as the background of my recyclerview list item.
touch_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true"
android:drawable="#color/green_text_500"/>
<!-- Default, "just hangin' out" state. The base state also
implements the ripple effect. -->
<item android:drawable="#drawable/touch_selector_base" />
</selector>
touch_selector_base.xml
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/light_grey">
<item android:id="#android:id/mask" android:drawable="#color/light_grey" />
<item android:drawable="#color/dark_grey"/>
</ripple>
In the list item I am using the touch_selector.xml as follows in my list_item_quote.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="86dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:clickable="true"
android:focusable="true"
android:background="#drawable/touch_selector"
>
// layout
</LinearLayout>
SIMILARLY I have another xml drawable touch_selector_dark.xml and touch_selector_base_dark.xml
In my recycler-view-adapter I alternate between these two drawables based on the index. For even indexes I use the darker drawable and for the odd index I use the lighter background to produce an alternating effect. But the issue is that the ripple effect is not working.
Here are the colors:
light_grey = #5b5b5b
dark_grey = #212121
green_text_500 = #37863a
use this line in your recycleview list layout
android:background="?android:attr/selectableItemBackground"
try this
worked for me
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
I think your ripple file is not valid, you can check this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="#color/dark_grey"/>
</shape>
</item>
</selector>
You can use android:foreground="#drawable/touch_selector" to display the ripple effect and also use android:background="" to set any other drawable background.

How to make a ripple effect over a linear layout, without overriding the background color on its children?

I have a LinearLayout that looks like this.
I want each row to be clickable. The LinearLayout code for a row looks like this:
<LinearLayout
style="#style/home_menu_item_container"
android:id="#+id/home_menu_acronyms_button"
>
<ImageView
style="#style/home_menu_item_left"
android:background="#color/greyLight"
/>
<TextView
style="#style/home_menu_item_right"
android:text="#string/home_menu_option_2"
android:background="#color/grey"
/>
</LinearLayout>
How can I add a ripple effect that expands over the entire row (parent) - not just one child view in the row? The tricky part here is to let the ripple go over the two colored row.
So far, I found out the easiest way to do so is define a <ripple> in your drawable and then set the background of the LinearLayout to this drawable resource.
Define your drawable-v21/item_selector.xml
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/your_background_color">
<item android:id="#android:id/mask"
<!--color here doesn't matter-->
android:drawable="#android:color/white" />
</ripple>
Set the background of your LinearLayout to drawable/item_selector.
<LinearLayout
style="#style/home_menu_item_container"
android:background="#drawable/item_selector"
android:id="#+id/home_menu_acronyms_button" >
...
</LinearLayout>
Besides, if you don't have your own background color, then there is no need to define a item_selector at all. You can simply define background as android:background="?android:attr/selectableItemBackground" for your LinearLayout.
It is a little bit complicated for that what you need but I don't think there is another way,...
You need to put your ImageView's into a ListView so that every ImageView is a ListItem and then you can set the ripple but you also need to set drawSelectorOnTop="true" otherwise it won't work correctly
I too faced this problem, finally found a simple solution
In linear Layout just add android:clickable="true";
and set background with ur ripple effect as
android:background="#drawable/ripple_effect"
code:
<LinearLayout
android:clickable="true"
android:background="#drawable/ripple_effect"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Add your child views here -->
</LinearLayout>
add ripple_effect.xml in drawable
ripple_effect.xml:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#f87d05c2"
tools:targetApi="lollipop">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#f87d05c2" />
</shape>
</item>
</ripple>
<RelativeLayout
android:id="#+id/rll_privacy_policy"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="?android:attr/selectableItemBackground"
android:orientation="vertical">
<TextView
android:id="#+id/txt_privacy_policy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/layout_margin_16"
android:text="#string/privacy_policy"
android:layout_centerVertical="true"
android:textColor="#color/link_acc"
android:textSize="#dimen/txt_title_20" />
</RelativeLayout>
Another option is to make the ripple's background color transparent. This way only the ripple can be seen. The ripple's xml file (in your drawable-v21/ folder) is thus:
<-- Ripple in some ghastly color, like bright red so you can see it -->
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/red"
>
<!-- background color uses a transparent mask set to full #ffffff (white) -->
<item
android:id="#android:id/mask"
android:drawable="#android:color/white"
/>
Note that if you are supporting pre-lollipop devices, you need to have a dummy file with the same name in your drawable/ folder. An empty selector is sufficient for that file. And remember that those older devices will not ripple.
answer above dont work for me,
here is my solution:
ripple.xml:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:colorControlHighlight">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="?android:colorAccent" />
</shape>
</item>
</ripple>
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
>
...put het your design
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/ripple" />
</FrameLayout>

Android's selector for selected item does not work

I have a listview, where I want to highlight selected items in a custom way. I'm setting every item properties in the adapter's getView method, including itemView.setSelected(true).
The main layout defines the listview in the following way:
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="multipleChoice"
android:listSelector="#drawable/list_selector" />
(Playing with choice mode does not help either).
The list_selector is an almost empty stub:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#android:color/transparent" />
</selector>
I don't need specific styles for listview as a whole, so I'd leave a default one, but according to this answer, we need a selector for a listview for item selector to work. Anyway, without the list_selector the problem remains.
The listview item layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:background="#drawable/listitem_background"
android:orientation="vertical">
and it references the following listitem_background selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="#android:color/white" />
<item android:drawable="#android:color/transparent" />
</selector>
The problem is, that selected items do not have white background.
If I change android:state_selected="true" selector in the listitem_background to, for example, android:state_pressed="true", then the selector starts to work, that is item background becomes white if an item is touched.
So, I suppose, there is an error either in the selectors, or in the way how I select items.
I can write a workaround by setting background from Java or utilizing checkable states, but I want to understand and fix current problem with selectors. Thanks in advance.
What about adding this line in your item view?
android:background="?android:attr/activatedBackgroundIndicator"
For instance:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/activatedBackgroundIndicator"
android:orientation="vertical" >
<TextView
android:id="#+id/textViewListRowOption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical" />
</LinearLayout>
Then the selector looks something like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:exitFadeDuration="#android:integer/config_mediumAnimTime">
<item android:drawable="#drawable/list_pressed" android:state_pressed="true"/>
<item android:drawable="#drawable/list_selected" android:state_activated="true"/>
<item android:drawable="#drawable/list_default"/>
</selector>
And the list view:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/listViewMainFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:listSelector="#drawable/list_item_selector"
android:choiceMode="singleChoice">
</ListView>
</LinearLayout>
Try this one to change the selected list item.Put it inside the list view.
if (currentSelectedView != null && currentSelectedView != v) {
unhighlightCurrentRow(currentSelectedView);
}
currentSelectedView = v;
highlightCurrentRow(currentSelectedView);
private void unhighlightCurrentRow(View rowView) {
rowView.setBackgroundColor(Color.TRANSPARENT);//to set a color for un-seclected row
}
private void highlightCurrentRow(View rowView) {
rowView.setBackgroundResource(R.drawable.selector_img);//to set a color for seclected row
}

ListView item ListSelector drawable flickering

I have a custom drawable for my listSelection. When I select one Item it gets selected. But on selected when I scroll through the other items (scrolling up/down) the backgroung is flickering and sometimes it is also getting disappeared.
I am including my xml layouts:
ListView:
<ListView
android:id="#id/listView"
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:listSelector="#drawable/list_selector"
android:clickable="true"
android:divider="#drawable/separetor_drawable"
android:fastScrollEnabled="true"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:scrollbars="none" >
</ListView>
drawable layout: list_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<corners android:radius="6dp" />
<solid android:color="#color/grey" />
<size android:width="50dp" />
</shape>
Also I even I specify shape width the shape automatically fill_parent and that goes for height as well.
Any suggestions?
//try in your listview attribute as
android:cacheColorHint = "#00000000"
or
android:cacheColorHint="#android:color/transparent"
at java code, you should use
listView.setCacheColorHint(Color.TRANSPARENT);
Try this in your listview:
android:listSelector="#android:color/transparent"
android:cacheColorHint="#00000000"
android:focusable="false"
android:focusableInTouchMode="false"
Don't know if you got your answer, but we had a similar problem at one point. We fixed it by setting a background on the outer element in our listitem's layout file:
listitem.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#drawable/listselector"
...>
....
</RelativeLayout>
and then the drawable.. listselector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#color/blue" />
<item android:state_selected="true" android:state_pressed="false" android:drawable="#color/yellow" />
<item android:state_selected="false" android:state_pressed="false" android:drawable="#color/black" />
</selector>
The background xml file sets values for pressed, selected, and normal states and you can change the colors to other drawable's if you wish. Seemed to fix the weird background flicker problem we were having.

How to make flash effect when clicking on complex LinearLayout just like clicking on ListView item?

I have some kind ListView. All items in it are in rectangle shape, but the top one has round corners as shown in this photo. To create it I've cut the top stripe with corners and saved it as item_bg_white_top image and a stripe with 1px height saved as item_bg_white_line image. And this is how I've constructed it.
I want to make flash effect when clicking on ltest layout just like clicking on ListView item.
How I can do this?
I've tried the code below on ltest but it it didn't helped. When I tried this code on ltest_inner it just changed its background to black.
final LinearLayout ll = (LinearLayout)findViewById(R.id.ltest);
ll.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ll.setBackgroundResource(android.R.drawable.list_selector_background);
}
});
item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="#+id/ltest"
android:layout_width="300dp"
android:layout_height="33dp"
android:orientation="vertical">
<LinearLayout
android:id="#+id/ltest_inner"
android:layout_width="300dp"
android:layout_height="8dp"
android:background="#drawable/item_bg_white_top" />
<LinearLayout
android:layout_width="300dp"
android:layout_height="25dp"
android:background="#drawable/item_bg_white_line_repeat" >
</LinearLayout>
</LinearLayout>
item_bg_white_line_repeat.xml
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/item_bg_white_line"
android:tileMode="repeat" />
What you want to do is set up a selector and use it as the drawable for the background.
Create an xml file in your drawable folder and add a selector to it:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:state_pressed="true" android:drawable="#drawable/disabled_pressed_image" />
<item android:state_enabled="false" android:state_focused="true" android:drawable="#drawable/enabled_focused_image" />
<item android:state_enabled="false" android:drawable="#drawable/enabled_image" />
<item android:state_focused="true" android:drawable="#drawable/focused_image" />
<item android:state_pressed="true" android:drawable="#drawable/pressed_image" />
<item android:drawable="#drawable/default_image" />
</selector>
The drawables above reference images also in your drawable folder. You don't have to implement all the states. Those are just some possible combinations.
Then attach this as the background to your Linear Layout:
<LinearLayout
android:id="#+id/ltest"
android:layout_width="300dp"
android:layout_height="33dp"
android:background="#drawable/selector_file_name"
android:orientation="vertical">
where selector file name is simply the name you gave to the selector xml file I mentioned above.
Also consider removing the inner LinearLayouts. You can do what you are trying to do with a 9-patch, then you'll only have the one LinearLayout (which you could just change to an ImageView if it is not going to host other Views).

Categories

Resources