I have a LinearLayout view to which I need to set the background image programmatically. However, when this view gets the focus, I need to show a stroke around it.
What am I doing:
The background resource (view_onfocus_background.xml) to show onFocus effect:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true">
<shape android:shape="rectangle">
<stroke android:width="5dp" android:color="#F7CA18" />
</shape>
</item>
</selector>
In the layout XML, I am adding the background as follows to apply the background with onFocus effect.:
android:background="#drawable/view_onfocus_background"
However, in the code, I have to set the different background image to the layout.
myLayout.setBackgroundResource(R.drawable.custom_image);
So, obviously, the view_onfocus_background I added in the layout XML doesn't apply anymore!
Question:
How can I achieve onFocus effect as well as custom image background to the layout?
I figured out that there is no way I can apply background effect through XML as well as the image background to the LinearLayout. The only thing I could do is to have two LinearLayouts (parent and child). Apply XML to the parent layout. Apply image background to the child layout. Add some padding in the parent layout to show the onFocus effect.
Example:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/customFocusLayout"
android:padding="5dp"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:background="#drawable/view_onfocus_background"
>
<LinearLayout
android:id="#+id/customTestLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false"
android:padding="0dp"
android:layout_gravity="bottom"
android:background="#drawable/custom_image"
android:orientation="vertical">
<!-- more stuff here-->
</LinearLayout>
</LinearLayout>
Related
I have a custom view with a background drawable.
The drawable has an inside shape with padding. No padding is applied on the view itself.
Whenever I set a padding on the view programmatically using View.setPadding(left,top,right,bottom), the shape padding gets changed too and I honestly cannot figure out why.
The xmls are defined as follows:
Background drawable
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:attr/colorControlHighlight">
<item>
<shape android:shape="rectangle">
<corners android:radius="#dimen/radius_large" />
<solid android:color="#color/yellow" />
<padding
android:left="#dimen/spacing_large"
android:right="#dimen/spacing_large"
android:top="#dimen/spacing_medium_to_large"
android:bottom="#dimen/spacing_medium_to_large" />
</shape>
</item>
</ripple>
Custom view extending ConstraintLayout (edited)
The tools: attrs on the <merge> tag are simply used to render what the outcome will be in the layout preview.
As you know, <merge> is not a viewgroup, so it doesn't allow attrs such as background etc
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"
tools:background="#drawable/background_start_lesson"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
... />
<ImageView
... />
<TextView
... />
</merge>
In the constructor of my custom view, I simply set the R.drawable.background_start_lesson
And this of course just renders nicely as expected, with large paddings:
.....but if I just set the padding of the view itself to 0dp programmatically or via xml (and it should be already at 0dp, given that I specified none on the view!), this is what happens:
In conclusion, why does setPadding() change the <shape> drawable padding and not the padding of the view?
Sorry for my english, i want set background layout image only use getWindow(), like this:
getWindow().setBackgroundDrawableResource(R.drawable.bg_image);
And in bg_image
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<bitmap
android:src="#drawable/bg_shkaf" />
</item>
</layer-list>
but the picture is stretched. How can I stretch proportional to the picture?
I dont think you can specify a scale-type if you just assign the image to the window background.
What I have done in similar scenarios is wrap my layout in a parent FrameLayout with a child ImageView which does take the scaleType attribute. You then add in all of your existing layout views.
Example:
<FrameLayout>
<ImageView
android:src="#drawable/bg_image"
android:scaleType="fitCenter"
android:layout_height="match_parent"
android:layout_width="match_parent" />
<!-- all of your other views here ... -->
</FrameLayout>
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>
I would like to add padding between EACH item in a listview, but I would like to keep the default divider as I think it is aesthetically pleasing. Anything wider looks ugly.
I currently have:
<com.example.practice.MyListView
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:drawSelectorOnTop="false"
android:layout_below="#id/name" />
Now, I have tried using a transparent divider, and this succeeds at getting the spacing I want, but then I don't see the little line. And if I don't use a transparent divider than I have a huge thick ugly line. I want to keep the default line shown, and just add some spacing on the top part of each listview item.
You wouldn't be able to achieve what you want as simple as that then.
Step one: Set the divider as transparent, and make the height a tad larger:
<ListView
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="#android:color/transparent"
android:dividerHeight="8dp"/>
Step Two: In order to achieve the 'little line' effect, you can add a custom drawable as the list view item background, say the list view item is defined as 'list_item.xml':
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
<-- Add a Custom background to the parent container of the listview items -->
android:background="#drawable/list_item_selector"
android:orientation="vertical" >
<-- Rest of the item layout -->
</LinearLayout>
Of course, that item can be anything you like it to be, mine is:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape
android:shape="rectangle">
<stroke android:width="1dp" android:color="#color/bg_gray" />
<solid android:color="#android:color/white" />
</shape>
</item>
<item android:bottom="1dp">
<shape
android:shape="rectangle">
<stroke android:width="1dp" android:color="#FFDDDDDD" />
<solid android:color="#00000000" />
</shape>
</item>
</layer-list>
But that would then disable the 'Holo Selector' effect, where whenever you click, or highlight an item on the listview, there is a Holo Blue color drawn over it, that's why if you notice on the list item background we didn't use a layer list drawable, we used a selector named 'list_item_selector'.
Here's the selector, which uses the layer list drawable when not pressed, and uses a Holo-blue color when pressed:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="false"
android:drawable="#drawable/list_item_bg2"
/>
<item android:state_pressed="true"
android:drawable="#color/holo_blue"
/>
</selector>
EDIT for Comment
Absolutely possible, you can define a set height for list view items, however, it is recommended to set a minimum height, rather than a predefined height that never changes.
Say this is my list item layout:
<?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" >
<ImageView
android:id="#+id/grid_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/grid_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:layout_toRightOf="#+id/grid_image"
android:minHeight="48dp"
android:padding="8dp"
android:textIsSelectable="false" />
</RelativeLayout>
All needed would be,
Step One: Define the min height, or max height, as you prefer, in the dimens.xml file contained in the values/ folder. Why? Because the height should definitely change based on the layout, and you can define different dimens.xml for each device density.
in the dimens.xml, say:
<resources>
<!-- List Item Max and Min Height -->
<dimen name="list_item_min_height">48dp</dimen>
<dimen name="list_item_max_height">96dp</dimen>
<dimen name="list_item_set_height">64dp</dimen>
</resources>
And then use whichever value for the parent LinearLayout of you list item's layout.
<?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="#dimen/list_item_min_height" >
And that's it for that topic, now to center the text, it's even simpler:
If you are using a TextView and is wrapped into a RelativeLayout, use: android:layout_centerVertical="true"
If you are using a LinearLayout, use: android:layout_gravity="center_vertical"
and couple that with: NOTE This only works if you didn't set the height to wrap_content, otherwise it is irrelevant.
android:gravity="center_vertical"
Hope that helps.
I don't know if I understand your question precisely.
If you want the divider to be transparent so you see a peace of the background between each ListView so it gives a kind of 3D effect when scrolling. You could do it this way:
In your list_item xml give the LinearLayout the background color you want for example:
<LinearLayout
android:id="#+id/listItem"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dip"
android:orientation="horizontal"
android:background="#FFFFFF"
>
Then give your ListView a background color like this:
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragmentListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#android:color/transparent"
android:dividerHeight="8dip"
android:background="#0000FF"
android:cacheColorHint="#android:color/transparent"
android:drawSelectorOnTop="true"
/>
Now your ListView scrolls over your background
I hope this is what you wanted.
Also one more way to increase the spacing between the list items is that you add an empty view to your adapter code by providing the layout_height attribute with the spacing you require. For e.g. in order to increase the bottom spacing between your list items add this dummy view(empty view) to the end of your list items.
<View
android:layout_width="match_parent"
android:layout_height="15dp"/>
So this will provide a bottom spacing of 15 dp between list view items. You can directly add this if the parent layout is LinearLayout and orientation is vertical or take appropriate steps for other layout. Hope this helps :-)
you can simply use divider
see the following example
<ListView
android:id="#+id/activity_main_listview_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#android:color/transparent"
android:dividerHeight="10dp"
/>
here, in android:divider you can set color or make it transparent and in dividerHeight for add spce between items.
This is a solution for those of you who do not want the divider to be visible and still want to add more space. To get rid of the divider completely, set it to #null and set the dividerHeight to 0dp. Here is a generic ListView of mines.
<ListView
android:id="#+id/myListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff0000"
android:divider="#null"
android:dividerHeight="0dp"
android:layout_alignLeft="#+id/txtMake"
android:layout_below="#+id/txtMake"
android:fadeScrollbars="false"
android:scrollbarThumbVertical="#drawable/scroll_bar_color"
android:scrollbarStyle="outsideInset" >
</ListView>
Next, go to the xml file in which you use the adapter with to populate your listview. Go to your container (Example RelativeLayout...) and simply add in the following.
android:layout_marginTop="15dp"
This will actually add space for those of you who are not using the divider. Unlike the padding which just increases the box size, this will increase the distance between each item.
Inside the ListView tag in XMLfile add a dividerHeight tag and give it a value(the spacing you want between your list items).
It would provide you with suitable space between the list items.
Code:
<ListView
android:id="#+id/listid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:divider="#drawable/divi"
android:dividerHeight="60dp"></ListView>
Now create a drawable XML file (in this case name is divi). Inside it add a stroke tag and give it a width and that would do.
Code:
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="line">
<stroke
android:width="1dp"
android:color="#000000"
/>
</shape>
android:layout_width="match_parent"
android:textColor="#color/colorPrimary"
android:textSize="30dp"
android:layout_height="wrap_content"
Complete Code Here
I want to change the color of child divider of ExpandableListView by writing:
android:childDivider="#drawable/yellow"
in layout file. However, when I collapse the item, I found the background of the ExpandableListView turn yellow (#drawable/yellow) , but I just want to change the color of child divider. Who can tell me why? To my surprise, if I change it by java code like
expandableListView.setChildDivider(this.getResources().getDrawable(R.drawable.yellow));
it works normally. It is very weird, who can tell me the reason?
<!-- if I set childDivider in Layout xml, it can't work normally.
However, if set childDivider in java code, it work normally -->
<ExpandableListView android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:dividerHeight="2dp"
android:divider="#drawable/yellow"
android:childDivider="#drawable/yellow"
/>
create a drawable with small height and set it to childDivider
property
"child_separator.xml":
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#color/child_separator_color"/>
<size android:height="1dp"/>
</shape>
expandable list view:
android:childDivider="#drawable/child_separator"
Simply set child divider as the color of your choice.
<ExpandableListView
android:id="#+id/list_shopping"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:childDivider="#color/LightGrey"
android:dividerHeight="1dp" />
You just need to remove android:divider="#drawable/yellow" from your layout. This should resolve your problem if I understood it correctly.
Here is what I mean: