I am using view stub in my application. I am inflating the view stub to the layout and it is working fine. Now if you see the dummy_layout.xml there I have given the android:layout_height=20dp. What I need to do is to change that view stub height from 20 dp to Wrap_Content on a button click. How can I achieve this?
My ultimate goal is this. I have a button in it. when i click on it for first time I need to show the full layout of stub. and again when I click on it for the second time I need to animate the stub to slide down and show only a part of it.
dummy_layout.xml
<RelativeLayout
android:id="#+id/topLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:src="#drawable/ic_watch_pic" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="#color/dark_grey"
android:text="Button" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="Button" />
</RelativeLayout>
<ViewStub
android:id="#+id/viewStub1"
android:layout="#layout/stub_layout"
android:layout_width="wrap_content"
**android:layout_height="20dp"**
android:layout_alignParentBottom="true"/>
</RelativeLayout>
And here is my class:
public class DummyFragment extends Fragment {
private View mRootView;
private Context mContext;
private Button mButton;
private boolean isVisible = true;
private RelativeLayout mParentLayout;
#Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.dummy_layout,
container, false);
mContext = getActivity();
mButton = (Button) mTopLayout.findViewById(R.id.button1);
final ViewStub stub = (ViewStub) mRootView.findViewById(R.id.viewStub1);
**final View inflated = stub.inflate();**
inflated.setVisibility(View.VISIBLE);
final View viewstublayout = mRootView.findViewById(R.id.viewStub1);
mButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(isVisible)
{
isVisible=false;
inflated.setVisibility(View.VISIBLE);
}
else
{
isVisible=true;
inflated.setVisibility(View.INVISIBLE);
}
}
});
return mRootView;
}
}
You can change the width/height of a view by editing its LayoutParams. Example:
View stub = findViewById(R.id.viewStub1);
ViewGroup.LayoutParams lp = stub.getLayoutParams();
lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
stub.setLayoutParams(lp);
The better question is why you want to do this? Maybe there's a better way of achieving your goal.
Try this
final ViewStub stub = (ViewStub) mRootView.findViewById(R.id.viewStub1);
View view = stub .inflate();
inside button click
LayoutParams params = (LayoutParams) view.getLayoutParams();
params.width = LayoutParams.WRAP_CONTENT;
view.setLayoutParams(params);
Try this and let me know if works well.
LayoutParams lp = (LayoutParams) (YourView).getLayoutParams();
lp.height = newheight;
YourView.setLayoutParams(lp);
Related
I have an xml like this
<android.support.v4.widget.SlidingPaneLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/SlidingPanel"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="left">
<ListView
android:id="#+id/MenuList"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="right"
android:background="#101010"
android:orientation="vertical" >
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Button"
/>
</LinearLayout>
</android.support.v4.widget.SlidingPaneLayout>
Now I want to add it to my main layout, which is a framelayout I created by code. Here is what I did:
SlidingPaneLayout mSlidingPanel;
Button bt;
View slide_menu;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
slide_menu = mInflater.inflate(R.layout.activity_main, null);
//CREATE FRAMELAYOUT HERE
FrameLayout fr = new FrameLayout(this);
fr.setId(1);
ViewGroup scene1 = (ViewGroup) findViewById(fr.getId());
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
scene1.addView(slide_menu, lp);
//////////////
mSlidingPanel = (SlidingPaneLayout) findViewById(R.id.SlidingPanel);
mMenuList = (ListView) findViewById(R.id.MenuList);
appImage = (ImageView)findViewById(android.R.id.home);
TitleText = (TextView)findViewById(android.R.id.title);
bt = (Button)findViewById(R.id.button1);
for(int i = 0;i<imgID.length;i++){
CreateObject ob = new CreateObject(imgID[i], titleContext[i], null );
mObject.add(ob);
}
mListViewAdapter = new CreateListViewAdapter(this, mObject);
mMenuList.setAdapter(mListViewAdapter);
mSlidingPanel.setPanelSlideListener(panelListener);
mSlidingPanel.setParallaxDistance(200);
/*
mListViewAdapter.notifyDataSetChanged();
*/
bt.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if(mSlidingPanel.isOpen()){
mSlidingPanel.closePane();
}
else{
mSlidingPanel.openPane();
}
}
});
// SET CONTENTVIEW HERE
setContentView(scene1,lp);
But I always get
NullPointer error.
I think the problem is caused by findviewByID, because in description it says that: "Finds a view that was identified by the id attribute from the XML that was processed in onCreate", so it will always be null, but I don't know how to correct it.
The error is because you are calling findViewById() before you call setContentView(). Therefore there is no view, and it will return null.
Also, it's rarely a good idea to call .setId().
Why not just <#include/> the layout inside another? And setContentView the main layout?
I need to measure the width of an ImageView, but when i measure it after setting
android:adjustViewBounds on the ImageView the measuredWidth is incorrect...
What am i doing wrong and how should i fix this?
My layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/lines2"
android:orientation="vertical"
android:weightSum="917">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="143">
<RelativeLayout
android:id="#+id/rectangleLayout"
android:background="#drawable/customborder"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="#+id/circle"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#drawable/circle"
android:src="#drawable/circle"
/>
</RelativeLayout>
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
view = inflater.Inflate (Resource.Layout.pager1Fragment, container, false);
rectangleLayout = view.FindViewById<ViewGroup> (Resource.Id.rectangleLayout);
circle = view.FindViewById<ImageView> (Resource.Id.circle);
circle.Measure ( Android.Views.View.MeasureSpec.MakeMeasureSpec(0, MeasureSpecMode.Unspecified),
Android.Views.View.MeasureSpec.MakeMeasureSpec(0, MeasureSpecMode.Unspecified));
Initialize ();
return view;
}
public void Initialize ()
{
var rectanglePadding = (int)((double)circle.MeasuredWidth / 2d);
//measuredWidth is wrong when adjustviewbounds is set
Console.WriteLine ("padding " + rectanglePadding);
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams (RelativeLayout.LayoutParams.MatchParent, RelativeLayout.LayoutParams.MatchParent);
p.LeftMargin = rectanglePadding;
rectangleLayout.LayoutParameters = p;
}
Ok getting View asap when my fragment is created.
ImageView Example = (ImageView) parentview.findViewById(R.id.Example);
Example.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
#SuppressWarnings("deprecation")
#Override
public void onGlobalLayout() {
Example.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int width = Example.getWidth() <--- this gives you width.
}
});
Just convert your code to that and your set.
I want to create square buttons, but because I can't get the width by XML to assign it to button's height, I'm doing it by Java. So I do this:
View body = inflater.inflate(R.layout.picker_numeric, null);
Button up = (Button) body.findViewById(R.id.picker_numeric_up);
Log.d(TAG, "" + up.getWidth());
int height = up.getWidth();
up.setHeight(height);
........................
AlertDialog.Builder builder = new AlertDialog.Builder(activity)
.setTitle(title)
.setView(body)
........................
I used Log.d to confirm that getWidth() returns 0.
Anyone knows why this happens? I'm out of options.
EDIT:
After what MKJParekh and Simon said my code is this:
dialogContent.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/picker_numeric_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:baselineAligned="false"
android:padding="#dimen/padding_small"
android:weightSum="3"
tools:ignore="HardcodedText,UselessParent" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical" >
<Button
android:id="#+id/picker_numeric_up"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/padding_medium"
android:layout_marginRight="#dimen/padding_medium"
android:gravity="center"
android:text="+" />
<EditText
android:id="#+id/picker_numeric_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/padding_medium"
android:layout_marginRight="#dimen/padding_medium"
android:gravity="center"
android:inputType="number" />
<Button
android:id="#+id/picker_numeric_down"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/padding_medium"
android:layout_marginRight="#dimen/padding_medium"
android:gravity="center"
android:text="-" />
</LinearLayout>
</LinearLayout>
Method in dialog's creator class:
public void equalDimens() {
up.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int height = up.getMeasuredWidth();
android.util.Log.d("dd", ""+height);
up.setLayoutParams(new LinearLayout.LayoutParams(height, height));
down.setLayoutParams(new LinearLayout.LayoutParams(height, height));
}
Then in Activity's Class:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
createMyDialog();
LinearLayout mainLayout = (LinearLayout ) this.getLayoutInflater().inflate(R.layout.main, null);
mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
myDialogClass.equalDimens();
}
});
setContentView(mainLayout);
}
Without calling myDialogClass.equalDimens() I obtain this:
And calling the method I obtain this:
You need to measure your view before you can get height and width of the view.
You can do it like this,here ll2 is your any view object
ll2.measure(
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int height = ll2.getMeasuredHeight();
int width = ll2.getMeasuredWidth();
And after getting the height and width you will need to set them as,
ll2.setLayoutParams(new LayoutParams(width, height));
You view is measured and inflated but not yet drawn in onCreate.
You can use (amongst other solutions):
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
// get width here
}
If you can't use this, e.g. you have dialog boxes spawned from your activity, try a global layout listener.
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// inflate your main layout here (use RelativeLayout or whatever your root ViewGroup type is
LinearLayout mainLayout = (LinearLayout ) this.getLayoutInflater().inflate(R.layout.main, null);
// set a global layout listener which will be called when the layout pass is completed and the view is drawn
mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
// measure your views here
}
}
);
setContentView(mainLayout);
}
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"
I want to use ViewStub in android, so please help me. I have created
ViewStub stub = new ViewStub;
View inflated = stub.inflate();
How to use it programmatically?
Like the documentation says, ViewStub is a View that is inflated lazily.
You can declare a ViewStub in an XML file like this:
<ViewStub android:id="#+id/stub"
android:inflatedId="#+id/subTree"
android:layout="#layout/mySubTree"
android:layout_width="120dip"
android:layout_height="40dip" />
The android:layout attribute is a reference to the View that will be inflated next to a call of inflate(). So
ViewStub stub = (ViewStub) findViewById(R.id.stub);
View inflated = stub.inflate();
When the method inflate() is invoked the ViewStub is removed from its parent and replaced with the right View (the root view of mySubTree layout).
If you want to do this progammatically then your code should be something like:
ViewStub stub = new ViewStub(this);
stub.setLayoutResource(R.layout.mySubTree);
stub.inflate();
Simply a ViewStub is used to increase efficiency of rendering layout.
By using ViewStub, manually views can be created but not added to view hierarchy. At the runtime, can be easily inflated, while ViewStub is inflated, the content of the viewstub will be replaced the defined layout in the viewstub.
activity_main.xml we defined viewstub but not created first.
Simple example gives better understanding,
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="#+id/btn1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="create the view stub" />
<Button
android:id="#+id/btn2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hide the stub." />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<ViewStub
android:id="#+id/stub_import"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:inflatedId="#+id/content_import"
android:layout="#layout/splash" />
</RelativeLayout>
</LinearLayout>
At runtime, when we inflate, the content will be replaced with the layout defined in the viewstub.
public class MainActivity extends Activity {
Button b1 = null;
Button b2 = null;
ViewStub stub = null;
TextView tx = null;
int counter = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b1 = (Button) findViewById(R.id.btn1);
b2 = (Button) findViewById(R.id.btn2);
b1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (stub == null) {
stub = (ViewStub) findViewById(R.id.stub_import);
View inflated = stub.inflate();
tx = (TextView) inflated.findViewById(R.id.text1);
tx.setText("thanks a lot my friend..");
}
}
});
b2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (stub != null) {
stub.setVisibility(View.GONE);
}
}
});
}
So, Lets look at again the view hierarchy,
when we inflate the viewstub, it will be removed from the view hierarchy.
Here is an example for show/hide and change data of ViewStub at run time
activity_main.xml
<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/buttonShow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show View Stub"/>
<Button
android:id="#+id/buttonHide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hide View Stub"/>
<ViewStub
android:id="#+id/viewStub"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout="#layout/layout_of_view_stub"
/>
</LinearLayout>
layout_of_view_stub.xml
<TextView
android:id="#+id/textInViewStub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ViewStub Button"
/>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ViewStub viewStub;
private Button buttonShow;
private Button buttonHide;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonShow = findViewById(R.id.buttonShow);
buttonHide = findViewById(R.id.buttonHide);
buttonShow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showViewStub();
}
});
buttonHide.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
hideViewStub();
}
});
}
private void showViewStub() {
if (viewStub == null) {
viewStub = findViewById(R.id.viewStub);
// If you want to change data of ViewStub at runtime, you can do like this
View inflatedView = viewStub.inflate();
TextView textViewInViewStub = inflatedView.findViewById(R.id.textInViewStub);
textViewInViewStub.setText("ABC");
}
viewStub.setVisibility(View.VISIBLE);
}
private void hideViewStub() {
if (viewStub == null) {
return;
}
viewStub.setVisibility(View.GONE);
}
}