Drawable resolution in custom widgets - android

Good day, I am a little confused and sorry if it is dublicated, but I cant find correct answer. My task is to create widget (RadioButton, RatingBar) with custom drawables + make them high quality and not blur.
Here comes my problems and what I have tried. So, for example, I have custom drawable for radio buttons:
radioButtonArray[i].setButtonDrawable(R.drawable.radio_button_selector);
radio_button_selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/rb_unchecked" android:state_checked="false"/>
<item android:drawable="#drawable/rb_checked" android:state_checked="true"/>
</selector>
Now the problem is in quality of drawables. If I will add rb_unchecked.png and rb_checked.png in different folders (hdpi,mdpi,xhdpi...) with different px size, then my radio buttons will be enourmous big on some phone screens. Ok, next thing that I tried was to set programmatically width and height of my radio buttons, but found that it is hard and unefficient (for example, I have the same situation with RatingBar and I cant find how to set custom width and height of items in it). Another solution that I tried is to add rb_unchecked.png and rb_checked.png only to drawable folder with size of 18px*18px and, on the one hand it solved the problem, size is correct, but the radio buttons now are low resolution and kind of blur.
My quastion is what I am doing wrong? I expected that on devices with different dp android will take specific image in hdpi/xhdpi folder and scale it to specific size, but instead of this images from specific folders just wrap_content | crop in my custom widget?

I found the reason why my radiobutton drawable was enourmous big, I used following layout:
<RadioButton
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="30dp"
android:layout_height="30dp"
android:button="#drawable/radio_button_selector"/>
The right aproach:
<RadioButton
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="#drawable/radio_button_selector"
android:button="#android:color/transparent"/>

Related

How to tile image and put background color in android activity?

I am trying to create this as a background (blue bg with gray grid lines). Except I don't want to use this image since on larger or smaller screens it will stretch the grid lines and it won't look good. So I think the best way is to specify a background color and then draw another image (1x1 transparent tile) and have it tile/repeat. Does anyone know how to specify multiple backgrounds on 1 view in the styles.xml file?
So far I have this:
<style name="RegularView" parent="#style/BaseView">
<item name="android:background">#00112d</item>
<item name="android:background">#drawable/grid</item>
</style>
Also what is a good width size for a single square, I want it so that the squares fit evenly in the width and height of the screen. There shouldn't be like half a square on the last row or column, if that's possible..
Thanks
You can cut small portion of the image, like one square with border and then declare a xml bitmap resource in your res/drawable folder.
bitmap_resource.xml:
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/small_part_of_image"
android:tileMode="repeat"/>
after that just set this file as background in your view.
It will repeat itself until it fits the whole view.

Android ImageButton scale down on press

I want to add an ImageButton to my layout that has the effect of scaling down in order to look like it's being pressed. So I basically have the original image #drawable/scan and the pressed image which is #drawable/scanhot. Scanhot is basically the same image scaled down.
My code is the following but it doesnt seem to work.
As you can see I am using a Button as opposed to an ImageButton because a Button could at least "switch" different images. However it does not do anything with similar images like scan/scanhot
button_rescan.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:drawable="#drawable/scanhot"/>
<item
android:drawable="#drawable/scan"/>
</selector>
layout
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp"
android:background="#android:color/transparent">
<Button
android:id="#+id/fragment_radar_rescan_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/button_rescan"
android:layout_gravity="center_horizontal"
android:layout_centerHorizontal="true"/>
</RelativeLayout
It looks that drawable/scanhot are not the same size drawable/scan (in pixels). So if you want effect of "zoom" (or whatever) you should still keep image size the same for both images (i.e. 100x100) and with the same size make scanhot look smaller. If you already got images scalled as you want, just load the smaller one to Gimp or Photoshop and scale its canvas to the size of the other image (which is bigger I assume) and then save. In that case canvas for both will be the same and you avoid additional scalling from ImageView
The problem with what you are doing is that when you set a picture to a background, it automatically is blown up to fit the View. Instead, both pictures should have the same resolution, but the picture in scanhot should just look smaller.
In otherwords, both pictures should have a 132x29 resolution (or rather, they should both be the same size)

Android Overlaying images in layer-list

I am trying to create a custom drawable which includes a 9-patch background image (named custom_bg below) and a regular png image (accordion_up). The latter should not be scaled.
I tried several variations of something along the lines of:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#drawable/custom_bg"/>
<item
android:layout_width="10dp"
android:layout_height="10dp"
android:drawable="#drawable/accordion_up"
android:gravity="right" />
</layer-list>
Tried different values for layout_width/layout_height and also width/height but all I get is the accordion image is stretched to fill the entire view. I would like it to float at the top right of the view instead, scaled only to match the dpi of the device, but not expanded to fit the view. How can I do that?

Replacing existing drwable in imageview is wrong scaled on some devices

The Situation:
I have a imageview with a layer list of two drwables.
The frame drwable is 800x400px and the cover drawable is 800x380px.
Both images reside in the folder drawable
<ImageView
android:id="#+id/preview_img_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="0.9"
android:adjustViewBounds="true"
android:src="#drawable/result_preview"/>
The Drwable layer list in drawable/result_preview
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/cover">
<bitmap
android:gravity="left|top"
android:src="#drawable/cover" />
</item>
<item
android:id="#+id/frame">
<bitmap
android:gravity="left|top"
android:src="#drawable/frame" />
</item>
</layer-list>
This setup works as expected the cover is displayed framed on all devices. Now the user can replace the sample cover with another cover of the same size.
Replacing the cover in the layer list and leave the frame as is.
LayerDrawable layer = (LayerDrawable) getResources().getDrawable(R.drawable.result_preview);
InputStream coverIs = getContentResolver().openInputStream(Uri.parse(coverUri));
this.drwCover = (BitmapDrawable) BitmapDrawable.createFromStream(coverIs, coverUri);
drwCover.setGravity(Gravity.LEFT | Gravity.TOP);
//drwCover.getBitmap().setDensity(160);
layer.setDrawableByLayerId(R.id.cover, drwCover);
imageView.setImageDrawable(layer);
The Problem:
Replacing the current cover with a new one (same dimensions as old) produces different results depending on the Device used.
On a device with a 3.2 screen and a 480x320 resolution the cover replaced fits in the frame. On a device with a 3.7 and a 800x480 resolution the replaced cover is displayed smaller then the old one.
What I found out is that the drwable in the imageview on the small device has a intrinsic height of 800x400 same as the dimensions of the drawable.
On the bigger screen the intrinsic height of the drawable is 30% bigger.
I know the the intrinsic values may differ from screen to screen.
What I was expecting is that the drawable that replaces the old one should will be scaled up the same way the old one was to +30%. But this did not happen.
Question:
Is there a option to tell the imageview or the layer list to Adpt itself? I think there should be a way to do so because the system did it already at the beginning.
First, I'd suggest doing the cover/frame differently:
make your frame a nine-patch drawable, so you can define in the nine-patch the padding that will remain visible when the cover is drawn on top of it.
put the frame drawable as a background
set the cover as the src of the image, and not the layer list
don't forget to set a scaleType for your ImageView, play with the different options, so suit your needs.
<ImageView
android:id="#+id/preview_img_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="0.9"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:background="#drawable/frame"
android:src="#drawable/cover"/>
For other having the same problem. 9patch png is a solution to a problem I don't have.
So far the only thing that came close to solve the problem was to put my resources into the folder drawable-nodpi. Here is the reference to the docs

Getting my bitmaps on a canvas to always be "full screen"

So I have this canvas on where I paint bitmaps
An example would be a bitmap as a background.. so I will make this full screen on my 533x320 dip Samsung S2
So, when I load this same app on a, lets say, HTC with 480x320 dip.. my background image will now be larger then the screen - how is this normally handled?
I know some would might answer that I can just check the DIP sizes and use that.. which would also work for this background image.. but what about the 10 chess pieces I have where one of them is not out of the screen because it extends the 480dp of the HTC but works great on my 533dp S2?
How is this normally handled?
There are lot of ways to do that. Make sure you always use fill_parent or wrap_Content for your width and height attributes. In case of percentage based width's use LinearLayout for your layouts and use Layout_weight attribute for giving the width or height.
Remember to give width or height as 0dp if you are using layout weight attribute.
The way I did it is to make a drawable for the background /drawable/backrepeat.xml that repeats an image (metalgrid.jpg) in both directions.
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/metalgrid"
android:tileMode="repeat"
android:dither="true" />
Then I have a style
<style name="page_background_gen">
<item name="android:background">#drawable/backrepeat</item>
</style>
And then I use that style in my layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:id="#+id/relativeLayout1"
style="#style/page_background_gen"
android:layout_width="fill_parent">
....
</RelativeLayout>
This will fill the background with a repeated image without messign with the scale of the image.

Categories

Resources