To drag the Image on the screen I created my own class:
private class CustomImageView extends AppCompatImageView
In the constructor I want to set params:
public CustomImageView(Context context) {
super(context);
params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
params.bottomMargin = 50;
this.setScaleType(ImageView.ScaleType.CENTER_CROP);
this.setLayoutParams(params);
this.setWillNotDraw(false);
}
my activity_main.xml:
<RelativeLayout
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="com.example.eleizo.firstapplication.MainActivity">
</RelativeLayout>
I want to have actually as it would be :
<RelativeLayout
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="com.example.eleizo.firstapplication.MainActivity">
<ImageView
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:layout_marginBottom="50dp"
/>
</RelativeLayout>
Why string "params.bottomMargin = 50" doesn't work? I tried to set params = new RelativeLayout.LayoutParams(val1,val2) but it's no matter.
How set android:layout_marginBottom in RelativeLayout by code?
try using the LayoutParams while you are adding the view in the relative layout. ViewGroup.addView(View, LayoutParams) .
Something like this.
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
params.bottomMargin = 50;
relativeLayout.addView(new CutomImageView(context), params);
Try using MarginLayoutParams instead of LayoutParams.
if( params instanceof MarginLayoutParams )
{
((MarginLayoutParams) params).bottomMargin = 50;
((MarginLayoutParams) params).leftMargin = 10;
}
So your code would look like
public CustomImageView(Context context) {
super(context);
params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
if( params instanceof MarginLayoutParams )
{
((MarginLayoutParams) params).bottomMargin = 50;
}
this.setScaleType(ImageView.ScaleType.CENTER_CROP);
this.setLayoutParams(params);
this.setWillNotDraw(false);
}
Related
I have a linear layout like this:
<LinearLayout
android:id="#+id/linearLayoutImages"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="1">
</LinearLayout>
The following function gets a bitmap, sets it to an image view that has been created programmatically, then creates a trash can icon and puts the whole things into a relative layout and finally puts it into the linear layout. But there is a problem, I want the result to be like this:
but the result becomes like this:
Code:
fun setImage(bitmap: Bitmap){
try {
val params = RelativeLayout.LayoutParams(375, 375)
params.addRule(RelativeLayout.ALIGN_PARENT_TOP)
params.setMargins(9,0,9,0)
val imageViewShowPic = ImageView(this)
imageViewShowPic.setLayoutParams(params)
imageViewShowPic.id = View.generateViewId()
imageViewShowPic.requestLayout()
val params2 = RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT)
val relativeLayout = RelativeLayout(this)
relativeLayout.setLayoutParams(params2)
relativeLayout.requestLayout()
val params3 = RelativeLayout.LayoutParams(75,75)
params3.addRule(RelativeLayout.BELOW,imageViewShowPic.id)
params3.addRule(RelativeLayout.CENTER_VERTICAL)
val imageButtonDelete = ImageButton(this)
imageButtonDelete.setLayoutParams(params3)
imageButtonDelete.requestLayout()
relativeLayout.addView(imageViewShowPic)
relativeLayout.addView(imageButtonDelete)
linearLayoutImages.addView(relativeLayout)
imageViewShowPic.setImageBitmap(bitmap)
imageButtonDelete.setImageResource(R.drawable.ic_delete)
imageButtonDelete.setOnClickListener {
linearLayoutImages.removeView(relativeLayout)
}
}
catch (ex:Exception)
{
Toast.makeText(this,ex.message,Toast.LENGTH_SHORT).show()
}
}
Update
The linear layout itself is in a horizontal scroll view, if it makes any difference.
<HorizontalScrollView
android:id="#+id/horizontalScrollViewImages"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:padding="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/buttonAddPic">
<LinearLayout
android:id="#+id/linearLayoutImages"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="1"></LinearLayout>
</HorizontalScrollView>
(Posted solution on behalf of the question author).
I finally found the solution myself! I changed the relative layout to a vertical linear layout (I don't know if it matters or not):
val params2 = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
val linearLayout = LinearLayout(this)
linearLayout.setLayoutParams(params2)
linearLayout.orientation = LinearLayout.VERTICAL
linearLayout.requestLayout()
and then set the width of imageButtonDelete to match parent.
val params3 = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
val imageButtonDelete = ImageButton(this)
imageButtonDelete.setLayoutParams(params3)
imageButtonDelete.requestLayout()
imageButtonDelete.setBackgroundColor(Color.TRANSPARENT)
Set (RelativeLayout.CENTER_VERTICAL) to (RelativeLayout.CENTER)
val params3 = RelativeLayout.LayoutParams(75,75)
params3.addRule(RelativeLayout.BELOW,imageViewShowPic.id)
params3.addRule(RelativeLayout.CENTER)
and
android:layout_width="wrap_content" to android:layout_width="match_parent"
<LinearLayout
android:id="#+id/linearLayoutImages"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="1"></LinearLayout>
With the below code you can achieve the desired output.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayoutImages"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:weightSum="1"></LinearLayout>
In Your activity.
try {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(375, 375);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
params.setMargins(9, 0, 9, 0);
ImageView imageViewShowPic = new ImageView(this);
imageViewShowPic.setLayoutParams(params);
imageViewShowPic.setId(View.generateViewId());
imageViewShowPic.requestLayout();
RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
RelativeLayout relativeLayout = new RelativeLayout(this);
relativeLayout.setLayoutParams(params2);
relativeLayout.requestLayout();
RelativeLayout.LayoutParams params3 = new RelativeLayout.LayoutParams(75, 75);
params3.addRule(RelativeLayout.BELOW, imageViewShowPic.getId());
params3.topMargin = 30;
params3.addRule(RelativeLayout.CENTER_HORIZONTAL);
ImageButton imageButtonDelete = new ImageButton(this);
imageButtonDelete.setLayoutParams(params3);
imageButtonDelete.requestLayout();
relativeLayout.addView(imageViewShowPic);
relativeLayout.addView(imageButtonDelete);
linearLayoutImages.addView(relativeLayout);
imageViewShowPic.setImageResource(R.drawable.ic_launcher_background);
imageButtonDelete.setImageResource(R.drawable.ic_launcher_background);
} catch (Exception ex) {
Toast.makeText(this, ex.getMessage(), Toast.LENGTH_SHORT).show();
}
OUTPUT
I am trying to assign the attribute "app:layout_columnWeight" from code. I tried to "GridLayout.LayoutParams" and apply a style to a template. I need to use this attribute because "android:layout_columnWeight" does not work in Api <21.
PS: I'm using android.support.v7.widget.GridLayout not android.widget.GridLayout.
I attached the picture:
Thanks for your help.
EDIT: not exactly, I've tried many things ...
Layout-frame template (sample):
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/fonfo_monstruo"
style="#style/monstruo">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="none"
android:id="#+id/textView"
android:layout_gravity="center"
android:textColor="#ffffff" />
</FrameLayout>
Frame style:
<style name="monstruo" >
<item name="android:layout_margin" >5dp</item>
<item xmlns="http://schemas.android.com/apk/res-auto" name="layout_columnWeight" >1</item>
</style>
Grid on main XML layout:
<android.support.v7.widget.GridLayout
app:orientation="horizontal"
android:isScrollContainer="true"
android:id="#+id/grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:columnCount="3"
android:background="#cbb5ff"
android:layout_marginBottom="100dp" />
onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
android.support.v7.widget.GridLayout grid= (GridLayout) findViewById(R.id.grid);
android.support.v7.widget.GridLayout.LayoutParams params=new android.support.v7.widget.GridLayout.LayoutParams();
params.height=200;
params.width=0;
for (int i = 0; i < 10; i++) {
View newMonster=View.inflate(this,R.layout.layu_mosnter,null);
newMonster.setLayoutParams(params);
grid.addView(newMonster);
}
}
I have the problem too, my solution is:
GridLayout.Spec spec = GridLayout.spec(GridLayout.UNDEFINED, 1.0f);
GridLayout.LayoutParams lp = new GridLayout.LayoutParams(new MarginLayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT));
ItemView itemView = newChildView(mGridLayout);
lp.columnSpec = spec;
mGridLayout.addView(itemView, lp);
Try it:
((GridLayout.LayoutParams) button.getLayoutParams()).columnSpec =
GridLayout.spec(GridLayout.UNDEFINED, 1f);
if view have been add to layout
or in your code:
replace
android.support.v7.widget.GridLayout.LayoutParams params=new android.support.v7.widget.GridLayout.LayoutParams();
with
GridLayout.LayoutParams param = new LayoutParams(GridLayout.spec(GridLayout.UNDEFINED, 1f), GridLayout.spec(GridLayout.UNDEFINED, 1f));
I solved the problem using a "RecyclerView" is more efficient, if someone wants the code that asks me.
after this
grid.addView(newMonster);
add
((android.support.v7.widget.GridLayout.LayoutParams) newMonster.getLayoutParams()).columnSpec = android.support.v7.widget.GridLayout.spec(GridLayout.UNDEFINED, 1, 1f);
So if U want use new LayoutParams just create it every time with params:
import android.support.v7.widget.GridLayout;
...
for (int i = 0; i < 10; i++) {
View newMonster = View.inflate(this, R.layout.frame, null);
GridLayout.LayoutParams params = new GridLayout.LayoutParams(GridLayout.spec(GridLayout.UNDEFINED), GridLayout.spec(GridLayout.UNDEFINED, 1, 1f));
params.height = 200;
params.width = 0;
newMonster.setLayoutParams(params);
grid.addView(newMonster);
}
when I click on a RelativeLayout it change the size.
How can I make this change animated? So it looks like the rectangle grows to full screen?
My Layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:background="#ff000000">
<RelativeLayout
android:id="#+id/srLayout"
android:layout_width="62.5dp"
android:layout_height="132.5dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="false"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="10dp"
android:clickable="true"
android:onClick="sleepRoom"
android:background="#ffffffff"></RelativeLayout>
</RelativeLayout>
The code:
public void sleepRoom(View view) {
RelativeLayout sr = (RelativeLayout) findViewById(view.getId());
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) sr.getLayoutParams();
params.height = RelativeLayout.LayoutParams.MATCH_PARENT;
params.width = RelativeLayout.LayoutParams.MATCH_PARENT;
sr.setLayoutParams(params);
}
Simple trick that worked for me:
Adding:
android:animateLayoutChanges="true"
to the xml of the view whose layoutParams you are changing.
Then, adding this line of code in your Java/Kotlin code before changing the params:
Java:
((ViewGroup) sr).getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
Kotlin:
(sr as ViewGroup).layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
To explicitly animate in this case, your sleepRoom() should look like this.
public void sleepRoom(View view) {
final RelativeLayout sr = (RelativeLayout) view;
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) sr.getLayoutParams();
params.height = RelativeLayout.LayoutParams.MATCH_PARENT;
params.width = RelativeLayout.LayoutParams.MATCH_PARENT;
sr.setLayoutParams(params);
PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left", 0, 1);
PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top", 0, 1);
PropertyValuesHolder pvhRight = PropertyValuesHolder.ofInt("right", 0, 1);
PropertyValuesHolder pvhBottom = PropertyValuesHolder.ofInt("bottom", 0, 1);
PropertyValuesHolder pvhRoundness = PropertyValuesHolder.ofFloat("roundness", 0, 1);
final Animator collapseExpandAnim = ObjectAnimator.ofPropertyValuesHolder(sr, pvhLeft, pvhTop,
pvhRight, pvhBottom, pvhRoundness);
collapseExpandAnim.setupStartValues();
sr.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
sr.getViewTreeObserver().removeOnPreDrawListener(this);
collapseExpandAnim.setupEndValues();
collapseExpandAnim.start();
return false;
}
});
}
However, normally android:animateLayoutChanges="true" should work.
For more specifics from the man Chet Haase, see: https://www.youtube.com/watch?v=55wLsaWpQ4g
because RelativeLayout extends View you can use all the animations you are using on "regular views". for example try using animate.scale() and see if it suits you. a simple way of doing it will be something like
#Override
protected void onCreate (Bundle savedInstanceState) {
sr = (RelativeLayout) findViewById(view.getId());
sv.setVisibility(View.GONE);
scaleEnd = sr.getScaleX();
sr.setScaleX(0);
}
...
#Override
protected void onPostCreate (Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
sr.setVisibility(View.Visible);
sr.animate.scaleX(scaleEnd);
}
Also if you want a Lollipop kind of animation have a look at: Use the Reveal Effect
I can set ViewPager's height programatically by using vpTabs.getLayoutParams().height = DESIRED_SIZE; but it works only once at run time. now the question is how to set the height more than one time at runtime ?
activity_layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/rlActivityProfile"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.my.package.ProfileActivity">
<!--MainContainer-->
<com.my.package.widget.ScrollViewX
android:id="#+id/svxUserProfile"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!--Main Container-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!--Header-->
<RelativeLayout
android:id="#+id/rlProfileBanner"
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#color/listile_green">
<!-- SOME OTHER VIEW-->
</RelativeLayout>
<RelativeLayout
android:id="#+id/rlTabs"
android:layout_below="#id/rlProfileBanner"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!--Slider-->
<android.support.v4.view.ViewPager
android:id="#+id/vpTabs"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/stlControl" />
</RelativeLayout>
</RelativeLayout>
</com.my.package.widget.ScrollViewX>
<!--Transparent toolbar-->
<include
android:id="#+id/iAppBar"
layout="#layout/app_bar" />
</RelativeLayout>
The viewPager is initialized in onCreate() of MainActivity class
ViewPager vpTabs = (ViewPager) findViewById(R.id.vpTabs);
I am changing the viewPager's height from fragment using an interface like this
//Calling from fragment
int totalHeight = titles.length * EditProfileAdapter.ROW_HEIGHT;
vpListener.onViewPagerHeightChange(totalHeight);
in MainActivity
#Override
public void onViewPagerHeightChange(int height) {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.height = height; //left, top, right, bottom
vpTabs.setLayoutParams(params);
}
NOTE: The custom widget ScrollViewX is the same ScrollView but with a Custom ScrollListener.
define new layoutParams and set your viewPager to it then change the layoutParams's height this will do the trick, don't do it directly to its original params or changes won't effect the layout more than once, you also have to make sure that the condition you are using is correct, try to use this:
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
//setting margins around imageimageview
params.height=yourHeight; //left, top, right, bottom
//adding attributes to the imageview
viewPager.setLayoutParams(params);
instead of setting it directly
ViewGroup.LayoutParams params= tabPager.getLayoutParams();
params.height = 500; //500px
params.width = 500; //500px
viewPager.requestLayout();
first, get the LayoutParams for your ViewPager then assign the height for this LayoutParams
ViewGroup.LayoutParams lp = viewPager.getLayoutParams();
lp.height = ScreenUtils.convertDpToPixel(300, getContext());
I have this main.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="#drawable/ic_launcher"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#android:color/white"
android:orientation="horizontal" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:background="#drawable/barslide"
android:layout_marginLeft="500dp"/>
</LinearLayout>
</FrameLayout>
I want to create the same UI like in main.xml in java code. I try to code it but it doesn't work, it's not same as the xml. Here is the code:
void createUI(){
LayoutParams params1 = new FrameLayout
(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);
LayoutParams params2 = new android.widget.FrameLayout.LayoutParams(
android.widget.FrameLayout.LayoutParams.FILL_PARENT,
android.widget.FrameLayout.LayoutParams.FILL_PARENT,
Gravity.BOTTOM);
FrameLayout f1 = new FrameLayout(this);
f1.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
LinearLayout l2 = new LinearLayout(this);
l2.setOrientation(LinearLayout.HORIZONTAL);
l2.setLayoutParams(params2);
view1 = new page1(getBaseContext());
view360 = view1.img1(getBaseContext());
view360.setBackgroundDrawable(getResources().getDrawable(R.drawable.black1));
view360.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
slidebar = view1.img3(getBaseContext());
slidebar.setBackgroundResource(R.drawable.barslide);
slidebar.setLayoutParams(new LinearLayout.LayoutParams(300, LayoutParams.WRAP_CONTENT,Gravity.BOTTOM));
f1.addView(view360);
f1.addView(l2);
l2.addView(slidebar);
addContentView(f1, params1);
}
Your code doesn't quite replicate the xml layout(this was to big for a comment):
// replace THIS(from the constructors) with your context reference
FrameLayout fl = new FrameLayout(this);
fl.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
ImageView imv1 = new ImageView(this); // the first ImageView
imv1.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
imv1.setImageResource(R.drawable.ic_launcher);
fl.addView(imv1);
LinearLayout ll = new LinearLayout(this);
FrameLayout.LayoutParams llp = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
llp.gravity = Gravity.BOTTOM;
ll.setLayoutParams(llp);
ll.setBackgroundColor(Color.WHITE);
ImageView imv2 = new ImageView(this); // the second ImageView
DisplayMetrics metrics = getResources().getDisplayMetrics();
float width = 300f;
int pWidth = (int) (metrics.density * width + 0.5f);
LinearLayout.LayoutParams imvlp = new LinearLayout.LayoutParams(pWidth,
FrameLayout.LayoutParams.WRAP_CONTENT);
float margin = 500f;
int pMargin = (int) (metrics.density * margin + 0.5f);
imvlp.leftMargin = pMargin;
imv2.setLayoutParams(imvlp);
imv2.setBackgroundResource(R.drawable.food_image1);
ll.addView(imv2);
fl.addView(ll);
You'll have to modify it to use your object page1(I don't know exactly what are you trying to do there).
Also, are you sure you have to use the addContentView()(maybe setContentView?) method?(This method will add the views to the already present layout)