Cannot center view in RelativeLayout - java

I am trying to center a view within a parent RelativeLayout:
private void addLoadingAnimation() {
RelativeLayout mainView = (RelativeLayout) findViewById(R.id.medical_supply_tile_activity);
mainView.removeAllViews();
GifView gifView = new GifView(this);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
gifView.setId(R.id.loading_gif);
mainView.setBackgroundColor(getResources().getColor(android.R.color.background_light));
mainView.addView(gifView,layoutParams);
}
I have also tried adding layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0); before the CENTER_IN_PARENT line. Nothing seems to be working. It is always aligned to the bottom right.
Here is my parent view:
<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:background="#android:color/background_light"
tools:context=".MedecineTileActivity"
android:id="#id/medical_supply_tile_activity"
android:layout_gravity="left">
</RelativeLayout>
The gravity=left is because when the loading animation is removed, I insert fragments and want them to go to the left.

I have achieved this with TextViews and ImageViews by aligning the child View's right to the parent's right and also aligning the child View's left to the parent's left.
<TextView
style="#style/NewTextM2"
android:id="#+id/soft_dialog_info_item_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/<Parent>"
android:layout_alignLeft="#+id/<Parent>"
android:layout_alignRight="#+id/<Parent>"
android:gravity="center"
android:tag="item_text"
android:text="#string/text"
android:maxLines="1" />
This will align the view to the bottom center of the parent.

Related

How to center content of GridLayoutManager?

Just trying to center my RecyclerView horizontal.
Here is the xml:
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
And here the java code:
mRecyclerView = findViewById(R.id.recycler_view);
itemLayoutManager = new GridLayoutManager(this, 6);
mRecyclerView.setLayoutManager(itemLayoutManager);
...
mItemAdapter = new ItemAdapter(MainActivity.this, mItemList);
mRecyclerView.setAdapter(mItemAdapter);
When I run the application the recyclerview aligns left.
What exactly do I have to do to center the content so that the margin is the same left and right like in the example picture on the right side?
Create a class like to set paddings to item:
class SpacingItemDecorator (private val padding: Int) : RecyclerView.ItemDecoration()
{
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
)
{
super.getItemOffsets(outRect, view, parent, state)
outRect.top = padding
outRect.bottom = padding
outRect.left = padding
outRect.right = padding
}
}
Now in Your RecyclerView set paddingStart and paddingEnd, e.g 4dp :
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingStart="4dp"
android:paddingEnd="4dp"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="6"/>
When You create adapter just apply this item decorator:
val x = (resources.displayMetrics.density * 4).toInt() //converting dp to pixels
recyclerView.addItemDecoration(SpacingItemDecorator(x)) //setting space between items in RecyclerView
RecyclerView item:
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="6dp"
app:cardElevation="4dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/txtContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{Integer.toString(dataView.id)}"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
Result:
I faced the same issue recently and looked into the source code. There's no straight forward way to do this using GridLayoutManager. The other was is to use a GridView which is more customisable.
This is an alternate solution for you or any one else looking for a workaround.
I didn't want to change to a GridView so this is what I did. I set the RecyclerView's layout width to wrap_content and centered it horizontally within the parent (which in your case is a RelativeLayout so it will be something like android:centerHorizontally="true")
I knew the item width so I calculated the spanCount by dividing the screen width by the item width (plus any horizontal margins). Now I set the span count to the grid layout manager and it gets centered horizontally just how you want it.
Adding margins to you item's layout root play an important role here.

Scroll view is not working properly when adding through java code

RelativeLayout layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
layout = new RelativeLayout(this);
setContentView(layout);
ScrollView sc = new ScrollView(this);
sc.setBackgroundColor(Color.YELLOW);
sc.setLayoutParams(layoutParams(300, RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.ALIGN_PARENT_RIGHT));
RelativeLayout rl = new RelativeLayout(this);
rl.setBackgroundColor(Color.CYAN);
rl.setLayoutParams(layoutParams(300, RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.ALIGN_PARENT_RIGHT));
int k=0;
for(int i=0;i<15;i++){
ImageView iv1 = new ImageView(this);
iv1.setImageDrawable(getResources().getDrawable(R.drawable.ic_launcher));
iv1.setLayoutParams(layoutParams(200, 200,0));
iv1.setTranslationY(k);
k+=200;
rl.addView(iv1);
}
sc.addView(rl);
layout.addView(sc);
}
public RelativeLayout.LayoutParams layoutParams(int width,int height,int rule1){
RelativeLayout.LayoutParams lpb = new RelativeLayout.LayoutParams(width,height);
if(rule1 != 0){
lpb.addRule(rule1);
}
return lpb;
}
Output of code
when i'm using RelativeLayout without ScrollView then it is showing all images but when i'm using ScrollView then it is not showing all images.
Please check where is the problem in the code.
it should be in right alignment inside ScrollView.
Desired output
XML Code of desired output ,which i'm trying to convert in java code.
<ScrollView
android:layout_width="300px"
android:layout_height="match_parent"
android:layout_alignParentRight="true" >
<RelativeLayout
android:layout_width="300px"
android:layout_height="fill_parent"
android:background="#android:color/holo_purple" >
<ImageView
android:id="#+id/iv1"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/ic_action_home" />
<ImageView
android:id="#+id/iv2"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_below="#+id/iv1"
android:src="#drawable/ic_action_home" />
<ImageView
android:id="#+id/iv3"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_below="#+id/iv2"
android:src="#drawable/ic_action_home" />
<ImageView
android:id="#+id/iv4"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_below="#+id/iv3"
android:src="#drawable/ic_action_home" />
</RelativeLayout>
</ScrollView>
A ScrollView is a FrameLayout, meaning you should place one child in it containing the entire contents to scroll; this child may itself be a layout manager with a complex hierarchy of objects.
So when you are using Relative Layout it is displaying images but when your are using scroll view which doesnot contain all the images under one layout it doesnot work, so try putting all images under LinearLayout (recommend) or other layouts.

Views are invisible after they was added into ViewGroup

I'm adding views programatically into FrameLayout:
public class PixelGridView extends FrameLayout {
...
public void addViewWithoutCoords(TableView view, int column, int row) {
float x = column * mCellSideSize;
float y = row * mCellSideSize;
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(lp);
view.setLeft(0);
view.setTop(0);
view.setX(x);
view.setY(y);
view.setVisibility(VISIBLE);
addView(view);
}
...
}
However, all they are somehow invisible. getChildCount() returns count with all of them. getVisibility() for each added view also returns VISIBLE.
I can drag'n'drop such views from another ViewGroup into my Framelayout and when I do this, all earlier added views become visible.
view layout file:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<ImageView
android:id="#+id/ivTable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
<EditText
android:id="#+id/ivTableName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#color/style_table_grey"
android:textColor="#android:color/white"/>
</RelativeLayout>
Even If I add new view without drag everything become visible.
The item view of the FrameLayout and RelativeLayout can be overlapping. If two item views are in the same positions of FrameLayout, the first loaded item will be covered by the later item.
Try turn on the show layout bounds in developer option of your android devices,and find the position of your item.

Crash when setting parameter to layout in Android

Expected Result
Clicking on the toggle button will show up the menu and slide out the content view rightward. After animation is finished, the layout parameters of the content view gets updated to the final position.
Problem
When updating the final position of the content view, the statement mViewContent.setLayoutParams(params); causes the crash. The error message is java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams
Source Code
Main.java > public class MainActivity extends Activity {}
public void onToggleButtonMenuClicked(View view) {
// Is the toggle on?
boolean toggleTurnedOn = ((ToggleButton) view).isChecked();
if (toggleTurnedOn) { // If the toggle is turned on
// Show menu
LinearLayout mViewMenu = (LinearLayout) findViewById(R.id.linear_layout_menu);
Animation animMenuOn = AnimationUtils.loadAnimation(MainActivity.this, R.anim.anim_menu_on);
mViewMenu.startAnimation(animMenuOn);
LinearLayout mViewContent = (LinearLayout) findViewById(R.id.linear_layout_content);
Animation animContentOff = AnimationUtils.loadAnimation(MainActivity.this, R.anim.anim_content_off);
mViewContent.startAnimation(animContentOff);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(480, 800);
params.leftMargin = 384; // Shift 384 pixels from left screen border
params.rightMargin = -96; // Exceed 96 pixels from right screen border
mViewContent.setLayoutParams(params); // This statement causes crash!
} else {
// Hide menu...
} // End of toggle events handling
} // End of onToggleButtonMenuClicked()
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="329dp"
android:layout_height="wrap_content" >
<!-- The Menu View -->
<LinearLayout
android:id="#+id/linear_layout_menu"
android:layout_width="263dp"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/table_row_1_search_bar"
android:layout_width="match_parent"
android:layout_height="40dp"
android:weightSum="10"
android:orientation="horizontal" >
<EditText
android:id="#+id/edit_text_search_id"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="7"
android:hint="#string/edit_text_search_id"
android:textSize="14sp" />
<Button
android:id="#+id/button_search_id"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="3"
android:text="#string/button_search_id" />
</LinearLayout>
<!-- Other rows in the menu are omitted -->
</LinearLayout> <!-- End of Menu -->
<!-- The Content View -->
<LinearLayout
android:id="#+id/linear_layout_content"
android:layout_width="329dp"
android:layout_height="match_parent"
android:orientation="vertical" >
<ToggleButton
android:id="#+id/toggle_button_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onToggleButtonMenuClicked" />
<TextView
android:id="#+id/text_content"
android:layout_width="480dp"
android:layout_height="wrap_content"
android:text="#string/text_content" />
</LinearLayout> <!-- End of Content -->
</FrameLayout> <!-- End of the root linear layout -->
mViewContent params should be added with resp to your Parent view, suppose you have parent view as LinearLayout then, LinearLayout.LayoutParams must be used.
Explanation (Adapted from here):-
Take for example, LinearLayout.LayoutParams and RelativeLayout.LayoutParams, they are different independent classes. They store different additional information about child views... say..
LinearLayout.LayoutParams can associate weight value with each
view, while RelativeLayout.LayoutParams can't.
RelativeLayout.LayoutParams can have values like alightWithParent,above, below
with each view while LinearLayout.LayoutParams can't.
Although the code will not give compile time error because all LayoutParams have same parent class i.e. ViewGroup.LayoutParams. So, it is always essential, to assign Layout params with respect to parent layout..
make sure you imported the correct layout params
import android.widget.LinearLayout.LayoutParams;

Add TextView on top of Button?

I'm building a contacts app which displays big contact photos. I need to add a label with the contacts name of each contact on top of the button (near the bottom) however I don't know how to get two views on top of each other. I cannot simply use settext since I need to add a semi-transparent background to the label.
EDIT:
I managed to get it on top but I cannot figure out how to get it on the bottom of the button.
RelativeLayout icon = new RelativeLayout(context);
// Create button
Button button = new Button(context);
button.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
layout.addView(button);
// Create label
TextView label = new TextView(context);
label.setText(name);
label.setBackgroundColor(Color.argb(120, 0, 0, 0));
label.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
icon.addView(button);
icon.addView(label);
However the text appears on the top of the image and I want it to be on the bottom like this:
With xml this would be something like: android:layout_alignBottom="#+id/myButton" but I'm doing this programatically and I haven't found a way to do it. How can I place my label near the button?
Try this
<?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="vertical" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center" >
<Button
android:id="#+id/button1"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:gravity="right"
android:text="John"
android:background="#drawable/button_action_active" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="test textView" />
</FrameLayout>
</LinearLayout>
Dynamically you can do by
TextView lable = new TextView(this);
lable.setLayoutParams(new LayoutParams(android.widget.LinearLayout.LayoutParams.WRAP_CONTENT, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT));
lable.setTextSize(25);
lable.setGravity(Gravity.CENTER);
lable.setText("John");
Button button = new Button(this);
button.setBackgroundResource(R.drawable.button_action_active);
button.setLayoutParams(new LayoutParams(android.widget.LinearLayout.LayoutParams.MATCH_PARENT, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT));
FrameLayout fl = new FrameLayout(this);
fl.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
fl.addView(button);
fl.addView(lable);
setContentView(fl);
To do this you can use a frame layout. The documentation for frame layout can be found here - http://developer.android.com/reference/android/widget/FrameLayout.html
However, frame layout is depreciated (if I remember correctly). So instead I would recommend using a relative layout. In your relative layout you can set the position of the button and then give the textview the attributes android:layout_alignLeft=#id/somethingand android:layout_alignRight="#id/Something"

Categories

Resources