How can I set the scrollbar track thinner than the thumb in RecyclerView without using custom scrollView
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="0dp"
android:scrollbars="vertical"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:fadeScrollbars="false"
android:scrollbarSize="4dp"
android:scrollbarThumbVertical="#drawable/scroll_view_gradient"
android:scrollbarTrackVertical="#color/scroll_bar_track"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
I did this on my own, it looks 'nice' & it acts 'somewhat nice', but some things aren't tested enough, should be somewhat helpful at least. Can check it on this link as well. Also, this first is just visually, if you want to customize the length of the thumb, then you need to create a custom view and manipulate the offset. Since it isn't a part of the question(and this answer), I didn't write it, it can be found in the link above if someone does need it.
bottom, left, right & top are insets, you can think of them as paddings, they don't affect the layout size, but you should keep the top & bottom insets on track and thumb on the same size(for vertical recyclerviews, horizontal ones should use left & right).
Also manipulates the thickness of thumb and track, and stroke width places transparent pixels, so that track seems smaller than it actually is. Kudos to #Razvan S.
scrollbar_track.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="8dp"
android:left="8dp"
android:right="8dp"
android:top="8dp">
<shape>
<solid android:color="#color/scroll_bar_color" />
<stroke
android:width="3dp"
android:color="#android:color/transparent" />
<size android:width="4dp"
android:height="4dp" />
</shape>
</item>
</layer-list>
This doesn't need width & height properties, because recyclerview calculates the length automatically, and track width sets the thumb width.
thumb_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="8dp"
android:left="8dp"
android:right="8dp"
android:top="8dp">
<shape android:shape="rectangle">
<solid android:color="#color/scroll_bar_color" />
<corners android:radius="4dp" />
</shape>
</item>
</layer-list>
styles.xml
<style name="scrollbar_style">
<item name="android:scrollbarAlwaysDrawVerticalTrack">true</item>
<item name="android:scrollbars">vertical</item>
<item name="android:fadeScrollbars">false</item>
<item name="android:scrollbarThumbVertical">#drawable/thumb_shape</item>
<item name="android:scrollbarTrackVertical">#drawable/scrollbar_track</item>
</style>
recyclerview tag in your layout: style="#style/scrollbar_style"
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="#style/scrollbar_style" />
Now comes the 2nd part, if you want to manipulate the length of the thumb, you need to calculate the offset on your own. I did that by creating a Custom RecyclerView which implements ScrollingView, and calculated manually everything.
Hope this helped you, it did the job for me.
Also for those of you wondering, I used layer-list because it worked as I wanted it, if I switched to something else I didn't get the desired behavior. It's probably a bit flawed, and there might be a better solution somewhere out there, but I did this by trial&error until I produced something I could work with.
Related
I would like to add padding or space to the logo on both the sides and the code is added here.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:gravity="fill">
<item android:drawable="#color/ns_theme"></item>
<item>
<bitmap android:gravity="center" android:src="#drawable/logo" />
</item>
</layer-list>
I had the same problem, I tried to add padding to the item but it didn't change anything.
<item
android:left="16dp"
android:right="16dp">
<bitmap android:gravity="center"
android:src="#drawable/splash"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"/>
</item>
The problem was gravity="center", with it the padding were not applied.
Try using android: gravity = "clip_horizontal"
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/splash_color" />
<item
android:left="16dp"
android:right="16dp">
<bitmap android:gravity="clip_horizontal"
android:src="#drawable/splash"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"/>
</item>
</layer-list>
Use
android:bottom=""
android:left=""
android:right=""
android:top=""
Try this
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="fill">
<item android:drawable="#color/ns_theme"></item>
<item
android:bottom="20dp"
android:left="20dp"
android:right="20dp"
android:top="20dp">
<bitmap
android:gravity="center"
android:src="#drawable/logo" />
</item>
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/ns_theme" />
<item
android:drawable="#drawable/ic_logo"
android:left="#dimen/_16sdp"
android:right="#dimen/_16sdp" />
</layer-list>
The problem is probably that your logo is too big (The image file you are using has a pixel width that exceeds the pixel density of the device you are running it on).
Whether or not that is the case, it would probably be better to approach the problem considering the possibility that it could be run on ANY Android device with ANY screen size.
Considering that, there are several options better than simply adding padding in xml... For example, you could:
1) Wrap the image inside another view object that you can control the size and postion of as Bhavik Makwana suggested.
2) Just simply re-edit/resample your image to match the width of your target device and include the white space you desire in the image itself.
3) Design full splash screens that match the entire screen exactly (which combine foreground and background into one image), for example one with 1080 x 1920 resolution, and others for other screen sizes. That way you can control exactly how you want it to look, and the resolution will be 1-1 with no anti-aliasing or resampling.
4) Use this "9-patch" image approach to define an absolute width and height for your logo, but allow stretching of the white space around it to accommodate different screen sizes.
or, finally, the best way:
5) Use a constraint layout with guidelines in order to define the width of your logo in terms of percentage of parent width rather than absolute value.
Some other advice: Unless you are using technique #2 above, make sure you are using a logo.png file like this:
... NOT like this:
KaBOOYOW!
-Boober.
try this code:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/colorPrimary" />
<item>
<bitmap android:src="#drawable/logo"
android:gravity="center" />
</item>
</layer-list>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:gravity="center"
android:layout_height="match_parent"
android:layout_width="match_parent">
<item
android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp"
android:gravity="center"
android:background="#mipmap/logo" />
</layer-list>
I have created custom seekbar to make it work according to my need. There are two questions related to it.
Before it let me show you my code for seekbar
In android xml
<com.abc.projectname.customlayout.CustomHorizontalSeekBar
android:id="#+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_centerVertical="true"
android:max="7650"
android:paddingLeft="30dp" // Padding given to show thumbnail properly
android:paddingRight="30dp"
android:clickable="false"
android:paddingTop="20dp"
android:tag="drawable/seek_bar_layout_two"
android:thumb="#drawable/dial" />
CustomHorizontalSeekBar Is a class which I have created to get the tag from seekbar and set progress drawable value as whatever tag have supplied to support multiple theme
seek_bar_layout_two xml file
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+android:id/background"
android:drawable="#drawable/deselect">
</item>
<item
android:id="#+android:id/progress"
android:top="20dp"
android:bottom="20dp"
android:drawable="#drawable/lt_grey_seek_bar">
</item>
<!-- android:drawable="#drawable/loadingbar"> -->
</layer-list>
Here deselect is and highlighted image which I want to show as background of seekbar permanently.
lt_grey_seek_bar xml
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:clipOrientation="horizontal"
android:gravity="left" >
<shape android:shape="rectangle" >
<corners android:radius="5dp" />
<stroke
android:width="1dp"
android:color="#color/lt_grey_border" />
<gradient
android:endColor="#color/lt_grey_end"
android:startColor="#color/lt_grey_start" />
</shape>
</clip>
Questions
1) Can I give same background image for custom seekbar for enable and disable state? If yes than how? It is a special need from my client and it is not necessary to show disable state.
What I have tried:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/seek_bar_layout_two xml" android:state_enabled="false"/>
<item android:drawable="#drawable/seek_bar_layout_two xml" android:state_pressed="true"/>
<item android:drawable="#drawable/seek_bar_layout_two xml" android:state_selected="true"/>
<item android:drawable="#drawable/seek_bar_layout_two xml"/>
</selector>
But Still no success.
2) As you can see in my seekbar implementation I have given padding to show proper thumbnail. But when I click outside the drawn state of seekbar where this padding is available seekbar automatically turns into non highlighted form. How should I stop it?
Seekbar and its touch area by which it gets non highlight
Non highlight seekbar look
I have been trying lots of ways to make it work successfully but unable to do so. Can anyone provide me a solution.
This is what I have done in my custom seekbar class
Rect bounds = getProgressDrawable().getBounds();
setProgressDrawable(getResources().getDrawable(idByTag));
getProgressDrawable().setBounds(bounds);
I want to create a bar like this initially when progress is zero it will be a fade in color but and as progress goes on it will become bright on that part(This is best I can explain) main thing is i want bar to show all colors at the same time.
Clip your "on" drawable:
over your "off" drawable:
by using res/drawable/custom_progress_drawable.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- Background -->
<item
android:id="#android:id/background"
android:drawable="#drawable/custom_progress_bar_off"/>
<!-- Secondary progress - this is optional -->
<item android:id="#android:id/secondaryProgress">
<clip android:drawable="#drawable/custom_progress_bar_secondary" />
</item>
<!-- Progress -->
<item android:id="#android:id/progress">
<clip android:drawable="#drawable/custom_progress_bar_on" />
</item>
</layer-list>
From an Activity, use
Drawable progressDrawable = ResourcesCompat.getDrawable(getResources(), R.drawable.custom_progress_drawable, getTheme());
myProgressBar.setProgressDrawable(progressDrawable);
or in xml, use
android:progressDrawable="#drawable/custom_progress_drawable"
And here's the result when using android:max="10" in xml:
It's a little bit off, but you could use setMax() with something more like 10000 and do some offsetting calculations when calling setProgress() to make it cleaner.
Finally! I went on a mission to figure this out for you, so if this suffices, feel free to give me that bounty, haha.
Try using this in your layout:
<View android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight=".20"/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:orientation="horizontal"
android:gravity="center"
android:layout_weight="0.62">
<View android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight=".03"/>
<ProgressBar style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight="0.94"
android:progressDrawable="#drawable/progressmask"
android:progress="0"
android:max="10"
android:rotation="180"/>
<View android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight=".03"/>
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight=".18"/>
</LinearLayout>
which references this drawable (progressmask.xml):
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background">
<shape>
<corners android:radius="50dip" />
<gradient android:startColor="#00000000" android:endColor="#00000000" android:angle="270" />
<stroke android:width="1dp" android:color="#00000000" />
</shape>
</item>
<item android:id="#android:id/progress">
<clip>
<shape>
<corners android:radius="50dip" />
<gradient android:startColor="#aa000000" android:endColor="#aa000000"
android:angle="270" />
<stroke android:width="1dp" android:color="#00000000" />
</shape>
</clip>
</item>
</layer-list>
and this image (colorprogress.png)
What it does is set the image as the background of a linearlayout, which contains a progressbar. The progressbar adds a semi-transparent black mask to the image to make it appear that the lights are off.
NOTE: In order to get this affect, I had to monkey with the progress bar (i.e. flip it, and set it to only 10 intervals. You will have to do some math to get the progress to line up with the image. i.e. setprogress((100-trueprogress)/10). Sorry I did not do this part for you.
This is what it will look like at progress 50% (the small x's and triangles will disappear on the device)
I hope this answers your question!
Like already suggested i think you should go for an layer-list and set multiple drawables then.
Main problem on this is that i need to be resizeable. An fixed size solution would be quite easy to implement.
You can't actually set the progress bars to different colors. You can however use only the on drawable and get the effect that you want. You could just apply a layer mask. What I mean is add a Relative layout which is initially say dark grey throughout i.e the gradient has only ONE color which is dark gray. Now, use code to set the gradient color on the left programmatically. Obviously the color on the left is going to be transparent. Learn more about Linear Gradients. That's about it. You just need to calculate the position from where the right gradient starts, rather where the left gradient(transparent)ends.
This method is slightly flawed and may not work on ALL devices.
The flawless method would be to create multiple .9png images and set the drawable of the progress dialog programmatically every time.
I want the imagebutton to appear transparently on the screen so i have made android:background="#null" in the XML file so it has removed the gray border around the imagebutton.It solved my problem but when i click on the imagebutton it is not showing any background color. But i need some background color to appear on click. So I have added android:padding="3dp". It has removed the border on the sides but not on the top.
<ImageButton
android:id="#+id/btnphoto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/photo"
android:layout_x="4px"
android:layout_y="370px"
android:padding="3dp" />
Please help me.
Thanks in advance.
To change View aspect on state changes (click, press, focus, ...) you can use StateListDrawable as android:background. ColorStateList can be usefull too.
This post shows a good example of how to use.
android:background="#android:color/transparent"
or, if you want only some transparency, you can control it with the alpha channel.
Something like
android:background="#7F000000"
would be a partially transparent black.
You can try making your custum button background, using images or shapes in XML...
For example, this shape make one button state where the colors are transparent because they are ARGB type.
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="#EB363636" />
<corners
android:bottomRightRadius="7dp"
android:bottomLeftRadius="7dp"
android:topLeftRadius="7dp"
android:topRightRadius="7dp" />
<stroke
android:width="2dip"
android:color="#D1000000" />
</shape>
Then you can combine multiple shapes/images to make an button react the diferent states:
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:dither="true">
<item
android:state_window_focused="false"
android:drawable="#android:color/transparent" />
<item
android:state_pressed="true"
android:drawable="#layout/shape_btn"/>
<item
android:state_focused="true"
android:drawable="#layout/shape_btn"/>
<item
android:drawable="#android:color/transparent"/>
</selector>
After making your selector you can use it as your button background using android:background="NAME OF SELECTOR FILE"
Friends How To Display Border To Imageview ?
I Want To Result Like Mobile gallery all image display with border.
plz give me ans thanks for advance....
You can create a resource (layer drawable xml) for your ImageView's "border" (actually background), and declare in your theme that the ImageView's background resource is the drawable xml.
If you need this "border" to be changed based on the ImageView's state (focused, selected, etc.), then you should create more layer drawables, and put them together into a selector xml (state drawable).
Then in your theme you should set the ImageView's background to be this selector.xml.
Update
Below is a sample of how to specify a simple border to your images, that will result in
You have to
create a new layer drawable file (image_border.xml),
modify/create your styles.xml file
modify/create your colors.xml file
modify your layout xml file (or your code) to apply the style to the ImageView.
res/drawable/image_border.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<gradient android:angle="90"
android:startColor="#color/image_border_start"
android:centerColor="#color/image_border_center"
android:endColor="#color/image_border_end" />
</shape>
</item>
<item android:top="2dp" android:left="2dp"
android:right="2dp" android:bottom="2dp">
<shape android:shape="rectangle">
<solid android:color="#color/default_back_color" />
</shape>
</item>
</layer-list>
res/values/styles.xml
Add the following lines:
<style name="myImageView">
<!-- 3dp so the background border to be visible -->
<item name="android:padding">3dp</item>
<item name="android:background">#drawable/image_border</item>
<item name="android:scaleType">fitCenter</item>
</style>
res/values/colors.xml
Add the following lines:
<color name="image_border_start">#40990000</color>
<color name="image_border_end">#FF660000</color>
<color name="image_border_center">#FFFF3333</color>
And finally specify the style of your ImageView in your layout xml:
<ImageView android:id="#+id/my_image"
android:layout_width="100dp" android:layout_height="100dp"
android:src="#drawable/efteling"
style="#style/myImageView" />
You can use this XML file as a drawable instead of multiple files, but this
file is placed in drawable folder. In ImageView use this XML file as a
background drawable, like: android:background="#drawable/following code file
name".
I hope this is helpful for you.
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF" />
<stroke android:width="1dp" android:color="#000000" />
<padding android:left="1dp" android:top="1dp" android:right="1dp"
android:bottom="1dp" />
</shape>
I tried all the above solutions but they didn't work for me!
So I figured out a simple solution to this! :-)
I remember that I read about FrameLayout of Android in the following article saying that it helps us to stack up our UI elements on top of each other in the same order we add them up.
Solution:
<FrameLayout
android:layout_width="112dp"
android:layout_height="112dp"
android:layout_marginLeft="16dp" <!-- May vary according to your needs -->
android:layout_marginRight="16dp" <!-- May vary according to your needs -->
android:layout_centerVertical="true">
<!-- following imageView acts as the boarder which sitting in the background of our main container ImageView -->
<ImageView
android:layout_width="112dp"
android:layout_height="112dp"
android:background="#000"/>
<!-- following imageView holds the image as the container to our image -->
<!-- layout_margin defines the width of our boarder, here it's 1dp -->
<ImageView
android:layout_width="110dp"
android:layout_height="110dp"
android:layout_margin="1dp"
android:id="#+id/itemImageThumbnailImgVw"
android:src="#drawable/banana"
android:background="#FFF"/>
</FrameLayout>
Preview:
And that's it. You will get the following like imageView!
Pros and Cons:
I think this is pretty easy solution to be used in anywhere else and it's all the things you do sits in one single place so easier to modify it. However I don't like to having to add two ImageViews.