I am trying to add a Layout to a LinaerLayout. while creating my view for the first time the layout is add nicely which means that the inflate and the addView are working well. but when I click a button to do the process a second time and add the same view another time it works but the view is add on top of the first one.
The Fragment :
// onCreateView, I bind the container with his LinearLayout
mLnPricing = (ViewGroup) mRootView.findViewById(R.id.lnPricing);
//some stuff
private void createPriceBlock() {
mParent = LayoutInflater.from(getActivity()).inflate(
R.layout.block_pricing, null);
//binding some views
mIbAddPricing.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
createPriceBlock();
}
});
mLnPricing.addView(mParent,0);
}
block_pricing.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="wrap_content"
android:orientation="vertical" >
//some text fields
</LinearLayout>
main_lauyout.xml:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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" >
//some controllers
<LinearLayout
android:id="#+id/lnPricing"
style="#style/addLabels.AppTheme"
android:layout_height="wrap_content"
android:layout_marginTop="20dp" />
</ScrollView>
I don't know what's wrong with my code but for some weird reason the same code is working on another project.
What I expect: Add the new view at the position 0 and move the other views down.
what I have: The view is add on top of the previews one and a blank space is created below the view
The default orientation for a LinearLayout is horizontal. You've not specified an orientation for the LinearLayout that the new Views are being added to, so the old ones are being pushed off-screen to the right. Add android:orientation="vertical" to the lnPricing LinearLayout tag.
Related
I am working on an Android 4+ app which uses a quite simply layout: Multiple views are stacked using a LinearLayout within a ScrollView
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="HardcodedText,UseCompoundDrawables,UselessParent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
<!-- Top Container -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
<Button... />
</LinearLayout>
<!-- Hidden Container -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
... Some Content ...
</LinearLayout>
<!-- Bottom Container -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
... Some Content ...
</LinearLayout>
</LinearLayout>
</ScrollView>
The HiddenContainer should not be visible when the layout it created. Thus in the beginning the BottomContainer is directly beneath the TopContainer. A click on the Button within the TopContainer toggles the visibility of the HiddenContainer.
Doing this with hiddenContainer.setVisibility(hiddenContainer.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE) works find and without any problem. However it does not look good when the view suddenly appears or disappears. Instead I would like to animate the change.
I was surprised that I was not able to find an easy solution for this:
Using android:animateLayoutChanges="true" does work, however I am not able to control the animation.
While using a ValueAnimator to change hiddenContainer.setScaleY(...) gives me control over the animation setScaleY(0) makes the container invisible without reducing the space it occupies within the layout.
Using the ValueAnimator to change hiddenContainer.setHeight(...) might work, however I don't want to use a fixed height value when showing the container (e.g. hiddenContainer.setHeight(300)) but the height which is determined by the containers content.
So, how to solve this?
For animate your changes of layout (alpha, visibility, height, etc) you can use TransitionManager. For example: I have three static methods and use them when I want to animate layout changes:
public static final int DURATION = 200;
public static void beginAuto(ViewGroup viewGroup) {
AutoTransition transition = new AutoTransition();
transition.setDuration(DURATION);
transition.setOrdering(TransitionSet.ORDERING_TOGETHER);
TransitionManager.beginDelayedTransition(viewGroup, transition);
}
public static void beginFade(ViewGroup viewGroup) {
Fade transition = new Fade();
transition.setDuration(DURATION);
TransitionManager.beginDelayedTransition(viewGroup, transition);
}
public static void beginChangeBounds(ViewGroup viewGroup) {
ChangeBounds transition = new ChangeBounds();
transition.setDuration(DURATION);
TransitionManager.beginDelayedTransition(viewGroup, transition);
}
And when you want to animate layout changes you can just call one of this methods before layout changings:
beginAuto(hiddenContainerParentLayout);
hiddenContainer.setVisibility(hiddenContainer.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE)
I have a layout as indicated below:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible">
<LinearLayout
android:layout_height="match_parent"
...
The associated activity is like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_login);// here is the layout
}
I'm trying to make it visible in the following way:
LinearLayout layoutActLogin = (LinearLayout) findViewById(R.layout.act_login);
layoutActLogin.setVisibility(View.VISIBLE);
But Android Studio told me that there is an error about R.layout.act_login
findViewById is for views, not layouts.
You should put an ID in your view like:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible">
<LinearLayout
android:layout_height="match_parent"
...
Then get the view reference and make it visible
View viewActLogin = findViewById(R.id.my_view);
viewActLogin.setVisibility(View.VISIBLE);
You can not change visibility of Layout. you can only change visibility of Views inside.
You can assign id to you view by using android:id tag in you layout. You can read more about this here.
In your case. Just give some Id to your View/ViewGroup, and reference that View from your Activity and using findViewById method and change its visibility.
You're misunderstanding how layouts and views work. Layouts define what is shown on-screen to a user during an activity, set by calling setContentView() within the Activity's onCreate() method. Views are individual elements within the layout, which are accessed with the R.id prefix using findViewById().
In your example you'll need to apply an ID to the root ConstraintLayout (using android:id) to be able to access it:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parent_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible">
Then you can access it with:
ConstraintLayout layoutActLogin = (ConstraintLayout) findViewById(R.id.parent_layout);
layoutActLogin.setVisibility(View.VISIBLE);
EDIT Looking at your code I now realise you want to control the root ConstraintLayout, which makes my answer almost identical to Eduardo Herzer's. Leaving my answer up due to the added explanation at the beginning.
I have one layout which includes other layout inside. I tried to set onClikeListener on ImageView inside the included layout, but it's not working. But when I set background drawable it works. I don't know why. Here is my code:
//custom header
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sticky_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/iv_header_close"
android:layout_width="60dp"
android:layout_height="55dp"
android:background="#drawable/big_cross_icon" />
</LinearLayout>
//activity_detail
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f1f2f6">
<include
android:id="#+id/header"
layout="#layout/custom_header"/>
</RelativeLayout>
//in Activity
View header = findViewById(R.id.header);
iv_header_close = (ImageView)header.findViewById(R.id.iv_header_close);
iv_header_close.setBackgroundDrawable(getResources().getDrawable(R.drawable.big_edit_icon));
iv_header_close.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish(); //not working
}
});
I wonder why I can access to child view inside included layout but can't set OnClickListner. Thank you so much :)
Create your iv_header_close like this:
ImageView iv_header_close = (ImageView) findViewById(R.id.iv_header_close);
Instead of calling finish() Try to call YourActivity.this.finish()
What's happening is that, inside the onClick of your imageview, you don't have access to your activity so you have to access your activity using YourActivity.this if you want to access the methods of your activity.
In case anybody is having the same issue five years later...
Using the onClick attribute on the view (ImageView, Button... mine was a button) inside the included layout file fixes the problem. However, note that the onClick attribute is now deprecated
I want to create a layout like this:
I think the ScrollView is necessary, maybe like this:
<RelativeLayout>
<RelativeLayout id="fixed">
</RelativeLayout>
<ScrollView>
<RelativeLayout>
<Button...
<ListView....
<Button...
</RelatievLayout>
</ScrollView>
</RelativeLayout>
But it seems that add a ListView inside a ScrollView is not good idea.
Any idea to make it?
BTW, there are not only Button1 and Button2 outside the listview, there are more views, so I do not think add the views as foot or head is a good idea.
This is xml code
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout android:id="#+id/rlt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
</RelativeLayout>
Java code
LinearLayout llt = (LinearLayout)findViewById(R.id.rlt);
for(int i=0;i<12;i++)
{
final int k =i;
LinearLayout ll = new LinearLayout(this);
ll.setId(i);
ll.setOrientation(LinearLayout.VERTICAL);
TextView tv = new TextView(this);
tv.setText(" name:"+i);
ll.addView(tv);
ll.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
System.out.println("This is the printed text no"+k);
}
});
//ll.setBackgroundColor(Color.BLACK);
llt.addView(ll);
}
You can create your own ListView like this
First idea (not recommanded): Adding a ListView inside a ScrollView is a bad idea, because both are scrollable by default. You could use a LinearLayout instead of the ListView and create a custom onClickListener for the items.
<Scrollview>
<Button.../>
<LinearLayout>
<items.../>
</LinearLayout>
</Scrollview>
Second idea (recommanded) is to go with one ListView and create a custom Adapter extending BaseAdapter returning the Views for each row and holding the data. This means adding your Buttons and Items to the ListView and create a custom OnClickListener and Adapter to hold you Model. This Is the way I have used and I would do it again this way.
I your Adapter, you will need to Override:
getViewTypeCount - number of types of different row-layouts.
getItemViewType the type of the row.
getView returning the view for a position, here you need to inflate the layout and set the data.
This is a related question how to create a ListView with different types of rows.
I'm creating childview for viewflipper at runtime based on the no of records in database,
inflating a view and adding to viewflipper. While Clicking each childview of viewflipper, should have newviewflipper with some childs. How to achieve this?
ViewFlipper.xml
<?xml version="1.0" encoding="utf-8"?>
<ViewFlipper
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/flipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
CustomViewSample.xml
<?xml version="1.0" encoding="utf-8"?>
<com.sample.MjpegView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fullscreen_video"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Java Code
ViewFlipper viewflipper = (ViewFlipper)findViewById(R.id.flipper);
- **livevideocount** is an integer contains no of records from table.
for(int i=0;i<livevideocount;i++)
{
MjpegView mv = (MjpegView)inflater.inflate(R.layout.CustomViewSample,null);
mv.setVisibility(MjpegView.VISIBLE);
viewflipper.addView(mv);
}
Clicking this MjpegView object should generate another viewflipper with 3 childviews.
can anyone help me?
You should not directly inflate dynamic content into ViewFliper.
You should add dyna_layout as <LinearLayout /> or <RelativeLayout /> into your ViewFlipper.xml, consider dyna_layout as a ViewGroup:
ViewGroup parent = (ViewGroup)(viewflipper.findViewById(R.id.dyna_view));
MjpegView mv = (MjpegView)inflater.inflate(R.layout.CustomViewSample, parent);
mv.setVisibility(MjpegView.VISIBLE); //may use or not
parent.addView(mv);