Why does ImageButton quality blurs or reduces to worst? - java

My app has a ImageButton whose quality is too bad. The actual image dimensions are 4176*4176 (4176pixels) which looks completely fine when opened separately. But when I import this to android studio and assign it to a ImageButton, the quality of the image downgrades. I have been trying a number of ways to fix this but haven't succeeded yet. I'm completely new to Android Programming.I go to res/drawable then right click to create a new Image Asset and then specify the location which imports the png file.
Actual image:
Image inside studio:
Here is the code in activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:gravity="center"
android:orientation="vertical">
<ImageButton
android:id="#+id/police"
android:layout_width="317dp"
android:layout_height="295dp"
android:layout_centerInParent="true"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:background="#drawable/custom_button"
/>
</LinearLayout>
Custom button code which calls the image:
<item
android:state_pressed="true"
android:drawable="#mipmap/pressed" />
<item
android:drawable="#mipmap/defaultt" />
</selector>

You are actually referencing the image like Launcher icon in /mipmap directory.
I suggest reducing the image size which you are only using it for ImageButton and placing it inside /drawable with the quality you want or maybe smaller than the current one instead of placing it inside /mipmap directory.
Also, I don’t actually see the reason of how scaleType helps in ImageButton. You may wanna remove that line too.

I'd start by reviewing density independent pixels on Android. This is a good blog that covers the concept: https://www.captechconsulting.com/blogs/understanding-density-independence-in-android
The main issue is that your image (which is very high res) is getting compressed to fit inside of the image button. Typically, you would want to include image assets for different densities via different drawable resource directories (e.g., drawable-hdpi, drawable-xhdpi, drawable-xxhdpi).
However, these days, you can use vector drawables, which will reduce the need for having multiple assets for each density bucket, assuming you have the ability to generate SVG asset files: https://developer.android.com/guide/topics/graphics/vector-drawable-resources

Related

How to make scrollable long image page?

I am making activity showing TOS(Terms of Service) contents.
TOS text content is written very long single image, which should be scrolled. And confirm button is located below it.
Is there any best practice to make it?
I used ScrollView to scroll contents.
ScrollView contains ImageView and ImageButton.
First, I insert very long TOS content image by android:src attribute.
But, xxxhdpi image file is about 1MB size and height is about 18000 thus the app crashed (it shows 'canvas trying to draw too large bitmap' error)
After that, I try using image library which are Glide and Picasso. Using them, the error doesn't occur but image quality got degraded.
I searched and tried many solution to keep resolution and render speed but failed.
I think trying to use smaller image is better solution, but in emulator scroll speed and behavior was very strange when used src attribute to draw image.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scrollView">
<FrameLayout
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/imageview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"/>
<ImageButton
android:id="#+id/textview"
some code... />
</FrameLayout>
</ScrollView>
I am not sure if using single long image with scrollView to show TOS contents is correct or not. And not sure if it is possible to handle long image properly with ImageView.
Respectfully, you're making life difficult for yourself.
Having the TOS in image form only is unusual; the 'correct' approach is to have your TOS in text form, which would also be fastest to code.
If the TOS is composed elsewhere, and you don't wish to re-type it, then possibly feed the image to an online OCR service and see what comes back?
Alternately, use a WebView component connecting to a web server serving a page with only the TOS image. (But this is a bad idea, because now you'll need to set-up and maintain a web-server!)
Try to put image to drawable-nodpi folder
If you are using Glide try to use .thumbnail() attr
Add to Android manifest largeHeap attr
And at least decrease size of big image

Android Studio - Images Expand Buttons (and break weight rules?)

I have been working around an issue for far too long. Any time I drop an image into an ImageButton, the button expands to be very large. To try to fix this, I created a TableLayout with TableRows, where the TableLayout has a weightSum and the rows each have their own layout_weight. However, regardless of how much weight that I assign a row, the image blows up and compresses all of my other rows. In other words, the TableRows do not respect the layout_weight assigned to them.
Below, I have four rows with weights 4, 5, 3, 1, respectively. The ImageButton is in the 3rd row with layout_weight="3". However, as you can see, the row expands to fit the button image.
At any rate, this is a major issue when I have multiple buttons on the screen. I have created many buttons of the same exact size thinking that I would make them large, so they will scale well with larger devices. Once again, the problem is that they don't scale down to fit inside of a button, but they expand the button, destroying all of the layout_weights in the process.
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="13"
android:background="#drawable/edit_users_view">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="4"/>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="5">
<ScrollView>
<!-- Figure out button first -->
</ScrollView>
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="3">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/selector_cancel_button"/>
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</TableRow>
</TableLayout>
In addition - This issue may be in part with how I am storing my images. I have saved everything into my drawable folder, but nothing inside my mipmap folders. Though, I did try saving this cancel button into the mipmap-mdpi folder and loading it into the ImageButton, but the effect was exactly the same. Mipmap folders probably just set resolution, not size? I didn't expand my drawable folder because there are maybe 50 images/selectors inside.
<ImageButton
android:layout_width="XXdp"
android:layout_height="XXdp"
android:background="#drawable/selector_cancel_button"/>
Set a specific density pixel for your ImageButton, it will limit it from expanding.
This answer is more like a HACK. The right way to do it is to have respective different images for all your screen sizes.
ldpi, mdpi, hdpi, xhpdi, xxhdpi, xxxhdpi. There are multiple open threads here on Stack on how to achieve that. Hope that helps.
The best that I can recommend you is to get your images sliced on the highest resolution you are targeting, let's say your higher resolution you are targeting is 1080x1920. Get you screen designed on this resolution and get the images on the actual size from this screen design. Put that images in respective "drawable" not "mipmap" like for 1080x1920 the respective folder is "drawable-xxhdpi". Access your images though drawable folder and then you don't even need to use weights or even fixed sizes. It will work like a charm.
The problem is that I was working with a single layout size with a single drawable sized button. The fact is, there are different screen densities, and different images should go to each. For those new to android programming, you can see my project folders transform to be what they "should have been" from the start. Take a look below.
As a short note - androd:layout_weight="1" for example, refers to how important that layout is to the entire layout. Widgets or layouts with lower layout_weights are HIGHER PRIORITY than those with higher layout_weights. As far as I know know, weightSum and layout_weight aren't related, like I thought they were in my XML example.
_
I created different sized images and put them in their respective folders, where the first drawable folder is used for "selectors" only. Each folder has the same images, just 80 percent smaller than the last folder. Android automatically takes the correct image for you and adds it to the layout preview you are working with. Once I had all of the images for each folder size, I compressed the files, then added them to android studio. I no longer had any issues running my program on ANY phone. Not to mention it was a lot easier to work with my buttons since they weren't physically MASSIVE in size for small phones, and normal sized for XLarge devices.
If issues still persist with out of memory errors, one could increase the heap size in the manifest.xml, but it doesn't seem necessary unless you are making a game. I tried increasing the heap in my super small program, and I could see a speed difference on some devices - the lesson here is to avoid largeHeap="true" unless you REALLY need it
The bottom line is that, if you want a good program, there aren't shortcuts. Learning libraries such as Picasso take time as well. Pick your poison.
On a final note, you can see that there are now 4 layout folders. Each of them contained XML files that were programmed independently so that everything looks the same for each screen density. If we are being honest here, this was mostly copying and pasting with minor modifications to each XML. When making the XML files inside each folder, you name them the files the same names. So activityMain.xml would be created in all 4 folders, and the device running the application would pick the correct XML layout from the folder that the device see's fit for it's screen density. Quite amazing actually.

can I force android (API8) seekbar to have a specific color?

I'm using android SeekpBar in my android app (API8)
I want to change it's color to be always blue.
but nowadays the color depends on the device model.
is there a way to make it always blue?
<?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"
android:orientation="horizontal"
android:id="#+id/settingsSeekbarMain">
<SeekBar
android:id="#+id/settingsSeekbarBar"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_gravity="center_vertical|right"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"
/>
</LinearLayout>
You need to create a custom style for your SeekBar which has a different progress drawable.
Copy the file android-sdk-root\platforms\android-8\data\res\drawable\progress_horizontal.xml into your drawable-folder. Alter the colors as you see fit.
In your styles.xml, create a custom style which uses your custom background drawable:
<style name="CustomSeekbarStyle" parent="#android:style/Widget.SeekBar">
<item name="android:progressDrawable">#drawable/custom_progress_horizontal</item>
</style>
To use your custom style, either set it explicitly for every SeekBar in your application like this:
<SeekBar
android:layout_width="match_parent"
style="#style/CustomSeekbarStyle"
android:progress="50"
android:layout_height="wrap_content" />
Or set the style globally in your application theme:
<style name="AppBaseTheme" parent="android:Theme.Light">
<item name="android:seekBarStyle">#style/CustomSeekbarStyle</item>
</style>
Edit 1: If your application uses newer themes on newer devices (i.e. holo-theme on ICS devices), you should consider overriding the progress_horizontal file for all relevant API levels. Create multiple drawable-vXX folders (i.e. drawable-v10 for GB, drawable-v14 for ICS) and put modified progress_horizontal.xml-files in those folders. You'll find those files in your android SDK as well.
Edit 2: This solution however does not come without a somewhat serious flaw: Device vendors like to create custom themes for their android firmwares, often involving different drawables and colors. Using the approach described above, those custom styles are overridden, possibly resulting in an inconsistent user interface.

Pinterest Style in Displaying Images with UIL

Pinterest Style of Displaying Images is exceptional, and this adds beauty to your app. After a couple of research I found out that there are great libraries out there that can display images like Pinterest do but not sure if this is compatible with UIL.
I am using the Universal-Image-Loader in displaying my images. In the image shown below I got my images displayed in that manner with some views together with it. It is undeniably true that UIL library handles phone memory greatly in displaying a lot the images. I'd like to know if it is possible to display my images like the Pinterest's but still using UIL as the generator. What are the possible resolve to this approach? Or maybe another library that only handles the display and compatible with UIL.
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:horizontalSpacing="4dip"
android:numColumns="3"
android:stretchMode="columnWidth"
android:verticalSpacing="4dip"
android:padding="4dip" />
Update:
I tried using the StaggeredGridView but the layout can't be cast to GridView.
<com.origamilabs.library.views.StaggeredGridView
xmlns:tools="http://schemas.android.com/tools"
xmlns:staggered="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview"
staggered:numColumns="3"
staggered:drawSelectorOnTop="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Hey Check out my implementation of Pinterest type view using Staggered GridView and Universal-Image-Loader here.

Help making a "launcher screen" for my app, and making it look right across devices

I posted a question here before: Good way to make a launcher screen for sub-apps within your app?, and then started working on other parts of the app, and now I'm back to the same thing.
I want to make a nice screen with icons that the user can press, with room for more icons at a later date. Or maybe something different, I'm not sure.
Here's a current screenshot of what it looks like:
It looks pretty bad there, on my phone it looks better, with less space between the apps (this is a friend's phone), but ideally I want it to look good on all devices.
My XML code for this is as follows:
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="20dp"
android:columnWidth="90dp"
android:stretchMode="columnWidth"
android:gravity="center"
android:background="#FF6699FF"
/>
Any tips/suggestions are appreciated, I want to make this look good.
I'm not sure what format to store the icons in, right now they're just large (400x400 or so) png files.
If your icons are just squares you might want to use a compressed format like jpg or gif to reduce your app's file size.

Categories