Add a child view to a parent layout with the same bounds - android

In a RelativeLayout I have 2 buttons: button and button2. These 3 itself lie inside the root view which is also a RelativeLayout.
What I am trying to accomplish here is that when button is clicked button2 should be removed from the inner RelativeLayout(its id is otherLayout) and get added to the root View which is rootView but with the same bounds as it was in the inner layout.
Here is my XML and Java code:
<?xml version="1.0" encoding="utf-8"?>
<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"
android:id="#+id/rootView"
tools:context="com.test.testproject.MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/otherLayout"
>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="53dp"
android:layout_marginTop="94dp"
android:text="One" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/button"
android:layout_marginStart="76dp"
android:layout_toEndOf="#+id/button"
android:text="Two" />
</RelativeLayout>
</RelativeLayout>
Java Code
public class MainActivity extends AppCompatActivity {
Button button,button2;
int mLeft,mRight,mTop,mBottom;
RelativeLayout otherLayout;
RelativeLayout rootView;
ViewGroup childParent;
int[] mBounds = new int[2];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
button2 = (Button) findViewById(R.id.button2);
// rootView = (RelativeLayout) findViewById(R.id.rootView);
rootView = (RelativeLayout) findViewById(R.id.rootView);
otherLayout = (RelativeLayout) findViewById(R.id.otherLayout);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Rect r = new Rect();
button2.getLocalVisibleRect(r);
// button2.getDrawingRect(r);
// ((ViewGroup)button2.getParent()).offsetDescendantRectToMyCoords(button2, r);
mLeft = r.left;
mRight = r.right;
mBottom = r.bottom;
mTop = r.top;
childParent = (ViewGroup) button2.getParent();
((ViewGroup)button2.getParent()).removeView(button2);
Handler mHandler = new Handler(Looper.getMainLooper());
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
button2.setTop(mTop);
button2.setLeft(mLeft);
button2.setBottom(mBottom);
button2.setRight(mRight);
/*
button2.setX(mBounds[1]);
button2.setY(mBounds[0]);*/
((ViewGroup)rootView).addView(button2);
}
},1000);
}
});
}
}
I tried a different methods but would work. I used getLocalVisibleRect(), getDrawingRect() and all (You can see in the commented code).
So how do I achieve this? Remember, that the requirement is that the View residing in the inner layout and after adding to root should have the same bounds and params and the position on screen also must not change.

I think that your issue may be with the layout parameters of button2. Probably the easiest way to approach this is to capture the position of button2 in the layout and set up new layout parameters. mLeft and mTop to be the left and top margins.
A simplified onCreate method is below, but I am curious about why this would be useful.
Also take a look at these caveats. The document for View specifies why setTop, etc. should not be called outside the layout system. (See here.)
setTop
void setTop (int top)
Sets the top position of this view relative to its parent. This method is meant to be called by the layout system and should not generally be called otherwise, because the property may be changed at any time by the layout.
#Override
protected void onCreate(Bundle savedInstanceState) {
Button button;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
button2 = (Button) findViewById(R.id.button2);
rootView = (RelativeLayout) findViewById(R.id.rootView);
otherLayout = (RelativeLayout) findViewById(R.id.otherLayout);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RelativeLayout.LayoutParams params;
int top = button2.getTop();
int left = button2.getLeft();
((ViewGroup) button2.getParent()).removeView(button2);
params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(left, top, 0, 0);
button2.setLayoutParams(params);
rootView.addView(button2);
}
});
}

Related

Moving buttons at desired locations

I have this problem: I want to put some Buttons at a certain locations, for example at the four squares of the screen (resolved) and I also want them to become red when clicking on each one, at exactly those locations (not resolved yet).
This is the main xml:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:layout_weight="15"
android:orientation="vertical">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:components="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/layout1">
<Button
android:id="#+id/one"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#color/colorPrimary"/>
<Button
android:id="#+id/two"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentEnd="true"
android:background="#color/colorPrimary" />
<Button
android:id="#+id/three"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:background="#color/colorPrimary" />
<Button
android:id="#+id/four"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:background="#color/colorPrimary"/>
</RelativeLayout>
</ScrollView>
</android.support.constraint.ConstraintLayout>
And this is the main java:
RelativeLayout layout = (RelativeLayout) findViewById(R.id.layout1);
RelativeLayout.LayoutParams rel_btn = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
Button btnTag = new Button(this);
btnTag.setLayoutParams(rel_btn);
btnTag.setBackgroundColor(Color.BLUE);
btnTag.setOnClickListener(listen);
layout.addView(btnTag);
}
private View.OnClickListener listen = new View.OnClickListener() {
#Override
public void onClick(View view) {
if (pressed != null) {
Button button1 = (Button) pressed;
button1.setBackgroundColor(Color.BLUE);
}
Button button2 = (Button) view;
GradientDrawable drawable = new GradientDrawable();
drawable.setShape(GradientDrawable.RECTANGLE);
drawable.setStroke(8, Color.RED);
button2.setBackgroundDrawable(drawable);
pressed = view;
}
in onCreate set up your buttons:
RelativeLayout layout = (RelativeLayout) findViewById(R.id.layout1);
RelativeLayout.LayoutParams rel_btn = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
Button one = (Button) findViewById(R.id.one);
one.setOnClickListener(listen);
Button two = (Button) findViewById(R.id.two);
two.setOnClickListener(listen);
Button three = (Button) findViewById(R.id.three);
three.setOnClickListener(listen);
Button four = (Button) findViewById(R.id.four);
four.setOnClickListener(listen);
and finally create your listener for all 4 of the buttons:
private View.OnClickListener listen = new View.OnClickListener() {
#Override
public void onClick(View view) {
GradientDrawable drawable = new GradientDrawable();
drawable.setShape(GradientDrawable.RECTANGLE);
drawable.setStroke(8, Color.RED);
Button button = (Button) view;
button.setBackground(drawable);
}
};
If you were created Buttons in the layout then why are you adding it dynamically.
If you are using layout then inflate these buttons using "findViewById()". And when user will click perform the action to that or all buttons.
one.setBackgroundColor(Color.RED);
But if you are using dynamic button creation then store all 4 button id's which you are creating. Then perform something like this.
buttonId[index].setBackgroundColor(Color.RED);
Make your main class implement to View.OnclickListener
public class MainFragment extends Fragment implements View.OnClickListener {
private void setUpViews() {
button1.setOnClickListener(this);
button2.setOnClickListener(this);
button3.setOnClickListener(this);
button4.setOnClickListener(this);
}}
#Override
public void onClick(View view) {
if(view instance of Button){
button.setBackgroundColor(getResources().getColor(android.R.color.holo_red_dark));
}
}
}
Well, if you give those buttons IDs, then you can change the color of them when you click it.
So if you tap on buttonID, do your logic and then change the color to buttonID.
// If you're in an activity:
buttonID.setBackgroundColor(getResources().getColor(R.color.red));
Add the color red to your color xml.
this can go inside of your onCreate. the buttonOne and buttonTwo at the IDs to the buttons in your XML.
This is the most BASIC way to do it. There are more ways, you can see those answers here too.
buttonOne.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//logic here
}
});
buttonTwo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//logic here
}
});
When you have a listener changing something is relatively easy. You do not need to implement different methods or check every button one by one. Since Button is a View as well, do the following pseudo-code.
// You need this if part, if you have other views that having the same listener.
// Otherwise, you do not need this if check.
if(is Clicked View is Button) {
// Now here, take the clicked view, which we know it is a button and change its colour.
}
By the way, the code above will be inside the overridden method onClick.
EDIT
To clarify, I am adding a small chunk of code.
#Override
public void onClick(View view) {
// Checking if the clicked View is a Button or not.
if(view instanceof Button) {
// view.getId() returns an integer.
Button clickedButton = (Button) findViewById(view.getId());
// Now, change the button's colour.
clickedButton.setBackground(........);
}
}
Hope it helps. Have a nice day!

Alignment of dynamic views

I want the alignment of the editext and the imageviewin the same horizontal line but I am getting the imageview below the edittext.
main fragment code
final LinearLayout lnrView = (LinearLayout)
child.findViewById(R.id.lnrView);
Button btnad = (Button) child.findViewById(R.id.btnad);
btnad.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
lnrView.addView(newedittext());
lnrView.addView(newImageview(getActivity()));
}
});
neweditext method
private View newedittext() {
final ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
final EditText editText = new EditText(getActivity());
int id = 0;
editText.setId(id);
editText.setTextSize(14);
editText.setTextColor(Color.rgb(0, 0, 0));
editText.setMaxEms(2);
editText.setInputType(InputType.TYPE_CLASS_TEXT);
return editText;
}
newImageview method
public ImageView newImageview(Context context) {
final ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
final ImageView imgView = new ImageView(context);
int id = 0;
imgView.setId(id);
imgView.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_close_red));
return imgView;
}
main fragment xml
<?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">
<Button
android:id="#+id/btnad"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="add" />
<LinearLayout
android:id="#+id/lnrView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
when i click the Add button an edittext and Imageview is created dynamically and my output screen look like below
i want the imageview and the edittext in the same line. can anyone help me.
when i add "Horizontal" this is the output
this my expected result
You need add first a Horizontal Linearlayout in Your lnrView than add EditText and Imageview
Try this
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LinearLayout layout = new LinearLayout(MainActivity.this);
layout.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
layout.setLayoutParams(lp);
layout.addView(newedittext());
layout.addView(newImageview(MainActivity.this));
lnrView.addView(layout);
}
});
Or simpler use
ListView
with
ArrayAdapter
where you define you own layout (EditText and button)
There is better way to manage add and remove lines.
Also you have all EditTexts in one array and you can do your logic simpler.

add bottom bar with function type onclicklistener

i have create a xml for a bottom bar.
Implements this bottom bar in other activity xml with this line of code:
<include layout="#layout/bottom_bar" />
where bottom_bar are the name of the file xml of the bottom bar.
I created a MainActivity and when i launch the app i see the MainActivity content with the bottom bar.
how to set an onclicklistener in one button of the bottom bar and make it work in every activity of my app?
this is the bottom_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/footer"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="80dip"
android:background="#ff44ff">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="1dip">
<ImageView
android:id="#+id/imageView1"
android:layout_marginLeft="1dip"
android:layout_marginRight="1dip"
android:layout_width="75dip"
android:layout_height="75dip"
android:background ="#drawable/icona" />
</LinearLayout>
</HorizontalScrollView>
this the MainActivity.java
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LayoutInflater layoutInflator = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout insertPoint = (LinearLayout) findViewById(R.id.ll_content);
List views = new ArrayList();
//create a dynamic view
Iterator<Notizia> it = (Dati.listaNotizie).iterator();
while (it.hasNext()){
final Notizia not = it.next();
View view = layoutInflator.inflate(R.layout.layout_notizie, null);
TextView textView = (TextView) view.findViewById(R.id.notizieTitolo);
int pixel = (int) (10 * getResources().getDisplayMetrics().density);
TextView textView1 = (TextView) view.findViewById(R.id.notizieSottoTitolo);
textView.setText(not.getTitolo());
textView1.setText(not.getSottoTitolo());
textView.setOnClickListener(new OnClickListener(){
public void onClick(View v){
Dati.setNewsListaAttuale("http://www.rhinos.it/rhinos-news/");
SingleNewsActivity.setNotizia(not);
Intent intent = new Intent(MainActivity.this, SingleNewsActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
});
view.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
views.add(view);
}
for(int i = 0; i<views.size(); i++)
insertPoint.addView((View) views.get(i));
}
}
I can create a java class or a function for the bottom bar and implement this class/function in the MainActivity.java ?
Set id
<include android:id="#+id/bottom_bar"
layout="#layout/bottom_bar" />
then
View bottom_bar_container = findViewById(R.id.bottom_bar);
bottom_bar_container.findViewById(R.id.<your id name which is use inside bottom bar>);
Set click listener
Set an id in the XML reference of the layout.
<include android:id="#+id/yourBottomBarId" layout="#layout/bottom_bar" />
Then get it in the activity class by Referencing it.
YourBottomBar bottomBar = (YourBottomBar) findViewById(R.id.yourBottomBarId);
Then get reference to the button contained in your bottomBar view.
// Unsure how you want to reference, this is one suggestion.
Button yourButton = bottomBar.getButton();
yourButton.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
// Your onClick implementation here.
}
});

Android: dynamically set the position of button into center of screen in RelativeLayout

There has been many questions on dynamically setting the position of a button, but I just want to change the position of a button into center of the screen. My layout is RelativeLayout.
Updated:
At the beginning, myButton has been set position in XML as:
<Button
android:id="#+id/myButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="Menu" />
Any suggestion would be greatly appreciated
See an example below (click the button and it will be moved to the center).
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="#+id/my_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="Menu" />
</RelativeLayout>
MainActivity.java:
public class MainActivity extends Activity {
private View mView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mView = findViewById(R.id.my_view);
mView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ViewGroup.LayoutParams vg_lp = mView.getLayoutParams();
// Make sure we are in RelativeLayout
if (vg_lp instanceof RelativeLayout.LayoutParams) {
RelativeLayout.LayoutParams rl_lp = new RelativeLayout.LayoutParams(vg_lp);
rl_lp.addRule(RelativeLayout.CENTER_IN_PARENT);
mView.setLayoutParams(rl_lp);
}
}
});
}
}
Try:
......
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) button.getLayoutParams();
layoutParams.leftMargin = parentLayout.getWidth()/2;
layoutParams.topMargin = parentLayout.getHeight()/2;
button.setLayoutParams(layoutParams);
......
Try this one:
RelativeLayout RL = (RelativeLayout)findViewById(R.id.relative_layout);
RL.gravity(Gravity.CENTER);
with this all subviews of RL will be in center;
Button anyButton = new Button(this);
RL.addSubview(anyButton);//this genereted button will be in center as well
Try this,
RelativeLayout my_layout = new RelativeLayout(this);
my_layout.setId(some_value);
Button my_btn = new Button(this);
RelativeLayout.LayoutParams my_params = new RelativeLayout.LayoutParams(btn_height,btn_width);
my_params.addRule(RelativeLayout.CENTER_IN_PARENT,my_layout.getId());
my_layout.addView(my_btn,my_params);
Add this 2 lines to the component you want to center in the xml file :
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"

Moving widgets in runtime on Android

I have a simple demo with two buttons. They are laid out with a RelativeLayout at the top and bottom of the screen.
When I click one of them, I want them to switch places.
What is the best way to do that?
This is my res/layout/main.xml :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageButton
android:id="#+id/android_button_1"
android:layout_width="200dip"
android:layout_height="wrap_content"
android:src="#drawable/icon"
android:layout_alignParentTop="true" />
<ImageButton
android:id="#+id/android_button_2"
android:layout_width="200dip"
android:layout_height="wrap_content"
android:src="#drawable/icon2"
android:layout_alignParentBottom="true" />
</RelativeLayout>
And this is my Activity:
public class HelloButtons extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ImageButton button1 = (ImageButton) findViewById(R.id.android_button_1);
final ImageButton button2 = (ImageButton) findViewById(R.id.android_button_2);
button1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Perform action on clicks
Toast.makeText(HelloButtons.this, "Beep Bop", Toast.LENGTH_SHORT).show();
}
});
button2.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Perform action on clicks
Toast.makeText(HelloButtons.this, "Beep Bop", Toast.LENGTH_SHORT).show();
}
});
}
}
Use something along these lines
RelativeLayout.LayoutParams lp1 = (LayoutParams) b1.getLayoutParams();
RelativeLayout.LayoutParams lp2 = (LayoutParams) b2.getLayoutParams();
lp2.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
lp2.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
lp1.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
lp1.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 0);
b1.setLayoutParams(lp1);
b2.setLayoutParams(lp2);
(and the opposite to revert them again) in you OnClickListeners
I would say the best way to do that is not to switch the actual ImageButton locations, but to instead switch the ImageButton images and keep track of the state inside your application so it can react to onClicks correctly.

Categories

Resources