Android ImageButton has unequal width and height - android

I have an 32x32 image in an ImageButton. Although layout_width and layout_height are set to wrap_content the ImageButton is shown as a rectangle with the height greater than the width. The container layout is a LinearLayout, nothing special around weighting the size of other widgets in this layout.
Why is this? It seems after I have upgraded my phone from 4.1.1. to 4.4 this strange behavior came in.

Is the image fixed size. If yes means you can mention the fixed size instead of using wrap content.
Or if it's dynamic means you can use the below SquareImageview
public class SquareImageView extends ImageView {
public SquareImageView(Context context) {
super(context);
}
public SquareImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
setMeasuredDimension(width, width);
}
}
Use this class in your app.
Then call this SquareImageView instead of ImageView and the layout_height should be match_parent

Related

Android studio how can i image size all screen

I have an image and ImageView of width 45dp & height 45dp. If I use my phone this image looks good but on another phone image seems very small. If you use picture converter and put xhdpi xxhdpi... the picture is still small.
(I want to get the same experience in all screen size. Example, in pixel 2 width 45dp height 45dp looks very good, Nexus width 65dp height 65dp very good, Samsung tab3 100dp looks very good. How can I do this?
Sorry for my poor English.
In the Dimens package of your application under res folder, use separate dimen values like dimens-ldpi, dimens-hdpi, dimens-mdpi, dimens-xhdpi, dimens-xxhdpi, dimens-xxxhdpi.
Create a value in each file and use different values for them.
Or, you can visit this question. There's multiple solution mentioned with example.
You need to maintain the aspect ratio of image view by calculating the ratio of screen width and height .
Create a Java File , say ProportionalImageView :
public class ProportionalImageView extends ImageView {
public ProportionalImageView(Context context) {
super(context);
}
public ProportionalImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ProportionalImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Drawable d = getDrawable();
if (d != null) {
int w = MeasureSpec.getSize(widthMeasureSpec);
int h = w * d.getIntrinsicHeight() / d.getIntrinsicWidth();
setMeasuredDimension(w, h);
}
else super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
then use this image View in your xml file :
<com.example.ProportionalImageView
android:layout_width="matchParent"
android:layout_height="wrapContent"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:src="#mipmap/img" />
Here , replace com.example. with your package name Hope it helps

setMinHeight and setMaxHeight in android custom view

Hi I want to set android custom buttons' setMinHeight and setMaxHeight
I have android button widget in the Library project and user of SDK(library project) can take use of that custom Button but I want to put restriction that button's Minimum size has to be 200dp and button's maximum height can not exceed 350dp how do i achieve that from custom view Button custom class?
Tried searching lot of thread but not sure yet.
public class MyCustomButton extends android.widget.Button {
public MyCustomButton(Context context) {
super(context);
applyDefaults(null);
}
public MyCustomButton(Context context, AttributeSet attrs) {
super(context, attrs);
applyDefaults(attrs);
}
public MyCustomButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
applyDefaults(attrs);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public MyCustomButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
applyDefaults(attrs);
}
private void applyDefaults(AttributeSet attrs) {
String height = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "layout_height");
String width = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "layout_width");
Log.e("MVYAS=======", "height===" + height);
Log.e("MVYAS=======", "width===" + width);
setUpButtonForLoginOrLogout();
setAllCaps(false);
setMinHeight(getResources().getDimensionPixelSize(R.dimen.mid_button_min_height));
setMinWidth(getResources().getDimensionPixelSize(R.dimen.mid_button_min_width));
setMaxHeight(getResources().getDimensionPixelSize(R.dimen.mid_button_max_height));
setMaxWidth(getResources().getDimensionPixelSize(R.dimen.mid_button_max_width));
}
}
and while using into layout.xml file
<com.example.library.widget.MyCustomButton
android:id="#+id/my_button"
android:layout_width="153dp"
android:layout_height="57dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignWithParentIfMissing="true"
android:layout_margin="10dp"
styleButton:mobileid="inverted"/>
Here user should not be able to create button height to 57dp as its lower than the desired button height.
Putting restriction by adding setMinHeight() and setMaxHeight() dose not work.
How do i achieve that. Your help appreciated.
Thanks in Advance.
Just add these below two methods in MyCustomButtom class and try it:
#Override
public void setMinimumHeight(int minHeight) {
super.setMinimumHeight(minHeight);
}
#Override
public void setMinHeight(#Px int minHeight) {
super.setMinHeight(minHeight);
}
And one more thing, add below line in applyDefaults() function.
setMinimumHeight(getResources().getDimensionPixelSize(R.dimen.mid_button_min_height));

Weight sum and square form

I have LinearLayout which contains two Button widgets with layout_weight=1. Depends on length of Button's text or screen resolution I get buttons with rectangular form (gray rectangles) but I need to keep the square form (blue squares).
I was trying to change height of LinearLayout param in onStart() method, depends on Button's width, but getWidth() returns 0. I understand that it's because view at that moment still not rendered. Please, help me to solve my problem.
There are many ways to achieve this. If you need to find the real width of an element, you can:
1) attach an OnGlobalLayoutListener to the view's ViewTreeObserver (but remember to remove it when you are done)
2) or you can manually measure what you need:
if(view.getMeasuredHeight() == 0){
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(metrics);
view.measure( metrics.widthPixels, metrics.heightPixels );
}
int realHeight = view.getMeasuredHeight();
//...your code
You are exactly right because at that time view will not be drawn so for that you have to use viewtreeobserver:
like this:
final ViewTreeObserver treeObserver = viewToMesure
.getViewTreeObserver();
treeObserver
.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
// TODO Auto-generated method stub
System.out.println(viewToMesure.getHeight()
+ "SDAFASFASDFas");
heith = viewToMesure.getHeight();
}
});
this view tree observer will be called after creating the view based on that you calculate and you can change.
You can use a custom view to set the view's height to be tha same as its width by overriding onMeasure:
public class SquareButton extends Button {
public SquareButton (Context context) {
super(context);
}
public SquareButton (Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareButton (Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth());
}
}
All you have to is use the custom button in your xml layout and you don't have to do anything in the activity:
<com.package.name.SquareButton
android:layout_with="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />

Rotated ( 90 degrees ) root ViewGroup

I am trying to create ViewGroup based on FrameLayout that might be rotated 90 degrees CW / CCW and it still will be working correctly
So far my results are not so sucesful. So far it looks like that ( left side before rotation, right after; sorry for bright red )
Layout for Activity
<?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">
<com.example.TestProject.RotatedFrameLayout
android:id="#+id/container"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00F"/>
</RelativeLayout>
RotatedFrameLayout
public class RotatedFrameLayout extends FrameLayout {
private boolean firstMeasure = true;
public RotatedFrameLayout( Context context ) {
super( context );
init();
}
public RotatedFrameLayout( Context context, AttributeSet attrs ) {
super( context, attrs );
init();
}
public RotatedFrameLayout( Context context, AttributeSet attrs, int defStyle ) {
super( context, attrs, defStyle );
init();
}
private void init() {
setRotation( 90f );
}
#Override
protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec ) {
super.onMeasure( heightMeasureSpec, widthMeasureSpec );
}
}
Some extra info
I don't want to use Animation rotation because buttons aren't clickable that way
I don't want to use landscape mode because in landscape on screen navigation buttons took a lot of space on Nexus 7 ( this is the main reason why I am trying to greate that rotated
It seems that only left and right side of the screen are out of bounds
It is quite hard to do and I think it is not worth doing. But if you really want to do this you need:
pass to ViewGroup correct size dimentions (swap width and height).
rotate ViewGroup canvas 90 degrees.
At this point everything should look fine, but touch events not working properly.
intercept all touch events and swap x and y. Then pass fixed events to ViewGroup.
I dont have any code samples and have never seen any ) This way should work, we did scale transformations with fragments where we had to fix touch events coordinates when fragment was scaled.
I havent tested it heavily but this works:
public class RotatedFrameLayout extends FrameLayout {
public RotatedFrameLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public RotatedFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RotatedFrameLayout(Context context) {
super(context);
init();
}
#SuppressLint("NewApi")
private void init() {
setPivotX(0);
setPivotY(0);
setRotation(90f);
}
#SuppressLint("NewApi")
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setTranslationX(getMeasuredHeight());
}
}

Get Eclipse to show custom component on graphical xml view

I have simply extended the ImageView so an image goes full width. Like so:..
public class BannerImageView extends ImageView {
public BannerImageView(Context context) {
super(context);
}
public BannerImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public BannerImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = width * getDrawable().getIntrinsicHeight() / getDrawable().getIntrinsicWidth();
setMeasuredDimension(width, height);
}
}
In XML I have declared it as follows:
<com.whatever.next.BannerImageView
android:id="#+id/banner"
android:src="#+drawable/logo"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
I receive the following errors:
main.xml: Unable to resolve drawable "com.android.layoutlib.bridge.ResourceValue#48537a0f" in attribute "src"
then I get the expected null pointer exceptions.
I am confused as I thought since I am not altering the default behaviour of the ImageView it would show in the graphical layout. I have read through the other similar questions and that confused me some more.
For the record the above code works fine on an actual device.
Any help is appreciated!
instead of
android:src="#+drawable/logo"
use
android:src="#drawable/logo"
No + for the src attribute

Categories

Resources