How to write XML code for width and heigh in Java - java

XML code
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:id="#+id/imageView"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="#drawable/pz"
android:layout_marginTop="5dp" />
I wrote it like this in java
ImageView imageView = new ImageView(MainActivity.this);
imageView.setImageResource(R.drawable.pz);
DisplayMetrics displaymetrics = new DisplayMetrics();
MainActivity.this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int width = displaymetrics.widthPixels;
int height = 300;
imageView.setLayoutParams(new ViewGroup.LayoutParams(width, height));
imageView.setId(i + 1);
li.addView(imageView);
But it looks strange , i want to change height to eg. 200 , instead of changing height it change width.Is there any better way to make it i just want width to MATCH_PARENT and height to be 200dp?

if you want to set any layout parameter to wrap_content or match_parent you should set ViewGroup.LayoutParams.MATCH_PARENT orViewGroup.LayoutParams.MATCH_PARENT constants for constructor parameters
and the constructor gets parameters in px so you have to change it to dp you can use this link

Related

Change a view margins programmatically

So I have a RecyclerView that has 250dp bottom margin
And I need to set the bottom margin programmatically to 0dp then set it back to 250dp, I have tried this but it's working just to set it 0dp and it doesn't work setting it to 250dp back:
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) linearLayoutRv.getLayoutParams();
params.setMargins(0,0,0,250); // params.setMargins(0,0,0,0); at first
linearLayoutRv.setLayoutParams(params);
There's some unnecessary things but here's the xml file :
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/linearLayoutRv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:layout_marginBottom="250dp"
android:gravity="center"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="51dp"
android:gravity="center">
//textview
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="51dp"
android:orientation="horizontal">
//some buttons
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="5dp"
android:padding="4dp"
android:scrollbars="vertical" />
</LinearLayout>
When you set margins programatically, you set value in pixels, not dp. Source of LayoutParams:
/**
* Sets the margins, in pixels. A call to {#link android.view.View#requestLayout()} needs
* to be done so that the new margins are taken into account. Left and right margins may be
* overridden by {#link android.view.View#requestLayout()} depending on layout direction.
* Margin values should be positive.
*
* #param left the left margin size
* #param top the top margin size
* #param right the right margin size
* #param bottom the bottom margin size
*
* #attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginLeft
* #attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginTop
* #attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginRight
* #attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginBottom
*/
public void setMargins(int left, int top, int right, int bottom) {
leftMargin = left;
topMargin = top;
rightMargin = right;
bottomMargin = bottom;
mMarginFlags &= ~LEFT_MARGIN_UNDEFINED_MASK;
mMarginFlags &= ~RIGHT_MARGIN_UNDEFINED_MASK;
if (isMarginRelative()) {
mMarginFlags |= NEED_RESOLUTION_MASK;
} else {
mMarginFlags &= ~NEED_RESOLUTION_MASK;
}
}
You need convert your dp to pixels:
Int yourDP = 250
Resources r = getResources();
float px = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
yourDP,
r.getDisplayMetrics()
);
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) linearLayoutRv.getLayoutParams();
params.setMargins(0,0,0,(int) px); // params.setMargins(0,0,0,0); at first
linearLayoutRv.setLayoutParams(params);
The problem is that setMargins accepts values not in dp (density independent pixels) unit but in px (pixel) unit.
You must convert your value of 250 to dp before passing it to the params object.
Context context = ...; // place 'this' if you are in an Activity or 'requireContext()' if you are in a Fragment
Resources res = context.getResources();
float dp250 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 250, res.getDisplayMetrics());
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) linearLayoutRv.getLayoutParams();
params.setMargins(0, 0, 0, dp250);
linearLayoutRv.setLayoutParams(params);
dp250 will result in a different number of pixels on different devices. It depends on the resolution and physical screen size.
You can easily do this with MotionLayout.
Just convert parent ConstraintLayout to MotionLayout, create MotionScene
and in code use transitionToEnd() and transitionToStart()
example
it was working but in pixels, so i added this method:
public static int convertDpToPixel(int dp, Context context){
return dp * ((int) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
and changed this:
params.setMargins(0,0,0,convertDpToPixel(250,getContext()));

Set Layout width percentage of the total screen width

Is there's way to set Button width 50% of the total screen size (from java code).
I have found a few answers but i would like to change Button size with java code instead of XML.
Try this out..
DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
ViewGroup.LayoutParams params = yourButton.getLayoutParams();
params.width = metrics.widthPixels;
try {
double ratio = 0.5;
params.height = Double.valueOf(ratio * height).intValue();
yourButton.setLayoutParams(params);
} catch (Exception e) {
e.printStackTrace();
}
Many ways to achieve this, you could try like below:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
ViewGroup.LayoutParams params= yourBtn.getLayoutParams();
params.width= width * 1/2;
yourBtn.setLayoutParams(params);
yourBtn.requestLayout();
It's so simple just do.
button.getLayoutParams().width = Resources.getSystem().getDisplayMetrics().widthPixels/2;
I hope it Helps
possible with of Guideline constraint
Guideline
Utility class representing a Guideline helper object for
ConstraintLayout. Helper objects are not displayed on device (they are
marked as View.GONE) and are only used for layout purposes. They only
work within a ConstraintLayout.
A Guideline can be either horizontal or vertical:
Vertical Guidelines have a width of zero and the height of their
ConstraintLayout parent Horizontal Guidelines have a height of zero
and the width of their ConstraintLayout parent Positioning a Guideline
is possible in three different ways:
specifying a fixed distance from the left or the top of a layout
(layout_constraintGuide_begin) specifying a fixed distance from the
right or the bottom of a layout (layout_constraintGuide_end)
specifying a percentage of the width or the height of a layout
(layout_constraintGuide_percent) Widgets can then be constrained to
a Guideline, allowing multiple widgets to be positioned easily from
one Guideline, or allowing reactive layout behavior by using percent
positioning.
See the list of attributes in ConstraintLayout.LayoutParams to set a
Guideline in XML, as well as the corresponding
ConstraintSet.setGuidelineBegin(int, int),
ConstraintSet.setGuidelineEnd(int, int) and
ConstraintSet.setGuidelinePercent(int, float) functions in
ConstraintSet.
<android.support.constraint.Guideline
android:id="#+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.50" />
**
Example
**
<android.support.constraint.ConstraintLayout 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">
<android.support.constraint.Guideline
android:id="#+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.50" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:text="TextView"
app:layout_constraintBottom_toTopOf="#+id/guideline4"
app:layout_constraintTop_toTopOf="#+id/guideline3"
tools:layout_editor_absoluteX="104dp" />
<android.support.constraint.Guideline
android:id="#+id/guideline4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.80" />
</android.support.constraint.ConstraintLayout>
Example with Layout height 50% of screen
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toTopOf="#+id/guideline4"
app:layout_constraintTop_toTopOf="parent">
</RelativeLayout>
<android.support.constraint.Guideline
android:id="#+id/guideline4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.50" />
2nd Way
getDefaultDisplay ()
public abstract Display getDefaultDisplay () Returns the Display upon
which this WindowManager instance will create new windows.
Despite the name of this method, the display that is returned is not
necessarily the primary display of the system (see
Display.DEFAULT_DISPLAY). The returned display could instead be a
secondary display that this window manager instance is managing. Think
of it as the display that this WindowManager instance uses by default.
To create windows on a different display, you need to obtain a
WindowManager for that Display. (See the WindowManager class
documentation for more information.)
Display mDisplay = getWindowManager().getDefaultDisplay();
final int width = mDisplay.getWidth();
final int height = mDisplay.getHeight();
// now simple height/2 use it as u want
something like this perhaps? Not sure if it will work exactly as you want it but thats the general idea of it
Configuration configuration = getActivity().getResources().getConfiguration();
int screenWidthDp = configuration.screenWidthDp;
final float scale = context.getResources().getDisplayMetrics().density;
int pixels = (int) (screenWidthDp * scale);
button1.setWidth(pixels*0.5);
Try
LayoutParams params = new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.setMargins(left, top, right, bottom);
yourbutton.setLayoutParams(params);
Resources r = mContext.getResources();
int px = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
yourdpmeasure,
r.getDisplayMetrics());

Square ImageView in the center of the screen

I would like to position ImageView in the center of the screen and set the width and height of the ImageView to the width of the screen.
I tried this, but the width of the ImageView is not equal to the width of the screen and ImageView is positioned in the top left corner:
DisplayMetrics displayMetrics = getApplicationContext().getResources().getDisplayMetrics();
float dpWidth = displayMetrics.widthPixels / displayMetrics.density;
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams((int)dpWidth, (int)dpWidth);
imageView.setLayoutParams(layoutParams);
In xml ImageView is in the center of the screen:
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="#+id/imageView"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
In Java code, setLayoutParams is overriding layout rules (params starting with layout_) you defined in xml.
You need to add the rules to keep centering the image.
Also LayoutParams will take integer in "pixels" not "dp".
So try this -
DisplayMetrics displayMetrics = getApplicationContext().getResources().getDisplayMetrics();
float dpWidth = displayMetrics.widthPixels;
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams((int)dpWidth, (int)dpWidth);
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
imageView.setLayoutParams(layoutParams);
Also, you might want to play with scaleType to let image fill the space.
Please check here for the available scaleType.
http://developer.android.com/reference/android/widget/ImageView.ScaleType.html

How to set relativelayout height equal to its width?

I searched a lot to find out how its gonna work and I got nothing.
I found some java code to do it dynamically but didn't work ant of theme and when opening the program, show a force close.
this is my code:
<LinearLayout android:baselineAligned="false"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<RelativeLayout
android:id="#+id/rlv1"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_weight="1"
android:background="#drawable/rectengle2" >
</RelativeLayout>
<RelativeLayout
android:id="#+id/rlv2"
android:layout_width="fill_parent"
android:layout_weight="1"
android:background="#drawable/rectengle" >
</RelativeLayout>
</LinearLayout>
as you can see I created a rectangle shape and used it in a relative layout with a lineaer layout as parent and i splitted that linear layout verticali to two part for each relative layout.
now i want to set these relative layout height equal to its width to get a pure square rectangle.
i tried many way but ... can help me any guy please?? thnaks..
The simplest solution, imo, is to subclass RelativeLayout, and override onMeasure, providing to the super the same size for width and height. For instance
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
as pointed out by #ZakTaccardi, declare it in your layout like
<com.example.subclassrelativelayout
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Finally I myself found out what to do in this situation. so i'm gonna explain how to solve for those who have or will have my problem.
in my xml ui file I set layout_weight=1 for a pair of relative layout that were in a linear layout to be splitted in the screen and actually width of each of them be the half of my screen width. my problem was about height and i tried many java codes to set relative layout height equals to its width.
finally i calculated the screen width in "DP" Term and set every relative layout's height to this. this is the solved code:
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);
float density = getResources().getDisplayMetrics().density;
float dpWidth = outMetrics.widthPixels / density;
RelativeLayout Rl1 = (RelativeLayout) findViewById(R.id.rlv1);
Rl1.getLayoutParams().height = (int) (dpWidth);
RelativeLayout Rl2 = (RelativeLayout) findViewById(R.id.rlv2);
Rl2.getLayoutParams().height = (int) (dpWidth);
so i got a pure square! Enjoy it. Thanks

How do you use a custom view in a HorizontalScrollView?

I've got a custom view (called CustomStrechView) which extends an ImageView. The point of this view is so that I can get an image to fill the view without losing the aspect ratio.
Now the CustomStrechView works fine when I use it in most applications, but when I try to apply it within my HorizontalScrollView, the images all seem to disappear. I'm not sure why this happens. I've tried removing the <HorizontalScrollView /> and when I do the images show back up, so I feel there is some property that needs to be set, but I can't seem to find it.
Can anyone point out what I’m doing wrong or a better way to get a custom view to work in a HorizontalScrollView?
Edit:
After playing around with this for a bit, I've determined that I can get the custom view to show the image only if I hardcode the width dimension, ie:
<com.example.dragdropshapes.CustomStrechView
android:layout_width="200dp"
Leaving the height as fill_parent is fine...
Code:
Here's how my custom view is being used in the xml file:
<!-- Removing this makes the images show up -->
<HorizontalScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
android:layout_marginTop="50dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:showDividers="middle"
android:orientation="horizontal">
<!-- Changing this to a normal ImageView makes the image show up -->
<com.example.dragdropshapes.CustomStrechView
android:id="#+id/pickshapes"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:clickable="true"
android:onClick="pickShapes"
android:background="#drawable/border"
android:src="#drawable/ic_launcher"
/>
<!-- There are 5 other custom ImageViews here -->
</LinearLayout>
</HorizontalScrollView>
Here's the major part of the custom view code:
public class CustomStrechView extends ImageView{
private final Drawable srcPic;
private final String TAG = "strechyTag";
private boolean changeSize = false;
private int Xpx;
private int Ypx;
public CustomStrechView(Context context) {
super(context);
srcPic = this.getDrawable();
}
//... other constructors, not really important...
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
Log.d(TAG, "in the onMeasure!!\n");
int width, height;
width = MeasureSpec.getSize(widthMeasureSpec);
height = width * srcPic.getIntrinsicHeight() / srcPic.getIntrinsicWidth();
setMeasuredDimension(width, height);
}
}
Through some debugging I was able to at least partially solve this myself. Turns out that the width acquired from the MeasureSpec.getSize(widthMeasureSpec); call was 0. Thus the calculation ended in width and height being 0 and the setMeasuredDimension call would then make the image invisible.
Now I'm saying I have this partially solved, because I still don't understand why I was getting that value of 0. I think it's because in a HorizontalScrollView the width isn't determined (it depends on the content within) thus whatever MeasureSpec.getSize(widthMeasureSpec); is actually doing is talking to the parent, and the parent in a normal Linear or RelativeLayout has a defined width where as in a HorizontalScrollView it does not... but that's just speculation at this point.
So I made a fix for it, if the width is 0 we run the calculation via the height instead. The height needed two cases to cover it to avoid divide by 0 errors (the else if and the else collectively).
Here's my current solution with the same xml file I noted in the Question.
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
if(width > 0)
height = width * srcPic.getIntrinsicHeight() / srcPic.getIntrinsicWidth();
else if(srcPic.getIntrinsicWidth() < srcPic.getIntrinsicHeight())
width = height / (srcPic.getIntrinsicHeight() / srcPic.getIntrinsicWidth());
else
width = height / (srcPic.getIntrinsicWidth() / srcPic.getIntrinsicHeight());
setMeasuredDimension(width, height);
}

Categories

Resources