CardView has lost margin when inflating - android

In my activity, I am setting the layout activity_main onCreate. I am then wanting to inflate my CardView for each of the items in my array.
So far, I've got everything loaded, however my CardView's have lost their margin. When added to the layout through XML, the margin works, but when its inflated as a separate XML file the margin is lost.
I am inflating the activity_main_card like so:
LinearLayout item = (LinearLayout)findViewById(R.id.card_holder);
View child = getLayoutInflater().inflate(R.layout.activity_main_card, null);
item.addView(child);
In the activity_main_card, my XML is as follows:
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="2dp"
android:layout_marginBottom="16dp">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:scaleType="fitCenter"
android:background="#drawable/cin"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#color/dark_grey"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textStyle="normal"
android:textColor="#color/grey_500"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
Can anyone point me in the direction where I am going wrong?

You're passing in null as the parent ViewGroup parameter to inflate(). This will cause all layout_* attributes to be ignored, as the inflater has no idea which attributes are valid for the container in which it will be placed (i.e. it has no idea which LayoutParams type to set on the View).
View child = getLayoutInflater().inflate(R.layout.activity_main_card, null);
should be
View child = getLayoutInflater().inflate(R.layout.activity_main_card, item, false);
For more info, see this great article about it -- it's a common mistake.

Related

Creating a custom menu using a layout inflator, how do I reference each component?

This is the item I'm inflating:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#drawable/background_border"
android:padding="10dp"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Account name"
android:textSize="25sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Balance: £61.43"
android:textSize="25sp"
android:paddingTop="40dp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_keyboard_arrow_right_black_24dp"
android:layout_alignParentEnd="true"
android:layout_centerInParent="true"/>
</RelativeLayout>
And I'm inflating it using the following code:
LinearLayout parent = (LinearLayout) findViewById(R.id.linearL);
view = getLayoutInflater().inflate(R.layout.menu_item, parent,false);
parent.addView(view);
Say if I inflated the following item three times, to create three menu items - how would I reference each item individually?
For example, if I wanted to change the text of the Account name in the first item of the menu, how would I reference that it's in the first item of the menu, instead of the second or third?
Say if I inflated the following item three times, to create three menu
items - how would I reference each item individually?
Use parent.getChildCount() and parent.getChildAt() for accessing Views from any R.layout.menu_item layout like:
Add layout multiple times:
//First time
parent.addView(view);
//Second time
parent.addView(view);
Get first added R.layout.menu_item layout view:
View firstView=parent.getChildAt(0);
In same way get other child View of parent layout.
Access child Views from firstView using :
View id if added in xml:
TextView textView=(TextView)firstView.findViewById(R.id.textViewID);
or using getChildAt method:
TextView textView=(TextView)firstView.getChildAt(0);
Access other views in same way.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#drawable/background_border"
android:padding="10dp"
>
<TextView
android:id="#+id/account_name_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Account name"
android:textSize="25sp"/>
<TextView
android:id="#+id/balance_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Balance: £61.43"
android:textSize="25sp"
android:paddingTop="40dp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_keyboard_arrow_right_black_24dp"
android:layout_alignParentEnd="true"
android:layout_centerInParent="true"/>
</RelativeLayout>
And in code you will have some thing like
TextView textview = (TextView)relativeLayoutFromXml.findById(R.id.balance_text_view);
textview.setText("sadsasa ");
If your layout is inside activity xml you should access the textview like this:
TextView textview = (TextView) findViewById(R.id.balance_text_view);
textview.setText("sadsasa ");

How should inflating go right way?

I need to have like several listviews on a scrollview which Android doesn't allow me to do so I decided to make it manually to simply inflate some listrows on a vertical LinearLayout, but everything goes not the right way
private void fillData(final ViewGroup parent, final ArrayList<Person> array ){
for (int i=0;i<array.size();i++){
final View view = lf.inflate(R.layout.personal_listrow, parent,true);
parent.setBackgroundColor(getActivity().getResources().getColor(R.color.background_light_darker));
view.setBackgroundColor(getActivity().getResources().getColor(R.color.background_night_lighter));
TextView tvName=(TextView) view.findViewById(R.id.tvName);
TextView tvStatus=(TextView) view.findViewById(R.id.tvStatus);
TextView tvGender=(TextView) view.findViewById(R.id.tvGender);
//fill textviews with info, set the onClickListeners and so on
}
So what I get - the view.setBackgroundColor paints parent as well .
parent is a vertical LinearLayout, view is horizontal LinearLayout - it's strange that I don't paint inflated element only so please explain me why
The next thing - after I add something to array - 1st element changes and all the rest is with unchanged text. However, I walked through the code with debugger - it passes every element and sets text.
The clicklisteners works on the 1st element only..
Would you plz explain
here's vertical , parent layout - nothing special:
<LinearLayout
android:id="#+id/rodll"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
the inflateable listrow is nothing special also :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView
android:id="#+id/tvStatus"
android:layout_width="0dp"
android:layout_weight=".3"
android:maxLines="1"
android:layout_height="wrap_content"
android:text="tvSt" />
<TextView
android:id="#+id/tvName"
android:layout_weight="1"
android:layout_width="0dp"
android:maxLines="1"
android:layout_height="wrap_content"
android:text="tvName" />
<TextView
android:id="#+id/tvGender"
android:layout_weight=".1"
android:layout_width="0dp"
android:maxLines="1"
android:layout_height="wrap_content"
android:text="tvGender" />
<com.andexert.library.RippleView
android:id="#+id/removeRipple"
xmlns:ripple="http://schemas.android.com/apk/res-auto"
android:layout_marginLeft="30dp"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginRight="7.5dip"
android:padding="3dp"
ripple:rv_alpha="255"
ripple:rv_zoom="true"
ripple:rv_zoomScale="0.8"
ripple:rv_type="rectangle">
<ImageView
android:id="#+id/remove_icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/remove" />
</com.andexert.library.RippleView>
<com.andexert.library.RippleView
android:id="#+id/addRipple"
xmlns:ripple="http://schemas.android.com/apk/res-auto"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginRight="7.5dip"
android:padding="3dp"
ripple:rv_alpha="255"
ripple:rv_zoom="true"
ripple:rv_zoomScale="0.8"
ripple:rv_type="rectangle">
<ImageView
android:id="#+id/add_icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/add" />
</com.andexert.library.RippleView>
</LinearLayout>
So. what's the problem and how to solve it?

getLayoutParams for LinearLayout under ScrollView not working

I have a LinearLayout and I controlled the height of this layout using getLayoutParams previously and it was working beautifully. Now I want the layout to be scrollable so I placed it under a ScrollView. Now for some reason the getLayoutParams stopped working. I seem to have come to a dead end trying to resolve this. Please help.
Here is my code
if(subHistories.getLayoutParams().height==0)
(subHistories.getLayoutParams()).height=ViewGroup.LayoutParams.WRAP_CONTENT;
else
(subHistories.getLayoutParams()).height=0;
Here subHistories is the layout object I want to control the height for. I want it to switch it's height from zero to wrap_content on every onClick event
And here is the relevant xml code:
...<ScrollView
android:id="#+id/left"
android:layout_width="200dp"
android:layout_height="fill_parent"
android:orientation="vertical"
android:layout_below="#id/head"
android:animateLayoutChanges="true">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/historyBut"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:background="#5261a5"
android:paddingBottom="5dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="5dp"
android:text="Historical Places"
android:textAllCaps="false"
android:textSize="20sp"
android:typeface="normal" />
<!-- historical places category -->
<LinearLayout
android:id="#+id/histories"
android:layout_marginLeft="10dp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:animateLayoutChanges="true" >...
After touching layout params, call requestLayout() for the changes to take effect.
For hiding/showing a layout, consider using setVisibility() with GONE and VISIBLE instead.

Insert a linearLayout inside another linearLayout

I'm trying to insert a LinearLayout inside another LinearLayout. I don't know if what I am doing is right or not. I need to try it this way, without using inflation.
LinearLayout address2;
address2 = new LinearLayout(this);
address2 = (LinearLayout)findViewById(R.id.sfsp2_layout);
LinearLayout teste3 = (LinearLayout)findViewById(R.id.se_contentAdressPostal);
LinearLayout teste4 = (LinearLayout)teste3.findViewWithTag("teste");
teste4.addView(address2);
LinearLayout teste3
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/se_contentAdressPostal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:background="#drawable/background_tile_address_postal"
android:orientation="vertical" >
<include
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="#layout/socio_form_structured_postal" />
LinearLayout teste4
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sfsp_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/background_tile"
android:orientation="vertical"
android:tag="teste" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sfsp_layout_horizontal"
android:layout_width="wrap_content"
android:layout_height="49dp"
android:layout_gravity="right"
android:background="#drawable/background_tile"
android:orientation="horizontal"
android:tag="teste" >
<Button
android:id="#+id/sfsp_btStructuredPostal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginBottom="2dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="2dp"
android:hint="#string/sfsp_btStructuredPostal" /> .......
LinearLayour address2 ( The layout that i need to insert in layout4)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sfsp2_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/background_tile"
android:orientation="vertical" >
<EditText
android:id="#+id/sfsp2_etStructuredPostalApartado"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:layout_marginLeft="65dp"
android:layout_marginRight="55dp"
android:layout_marginTop="2dp"
android:layout_weight="0.14"
android:ems="10"
android:hint="#string/sfsp2_etStructuredPostalApartado"
android:inputType="textMultiLine"
android:scrollHorizontally="false" >
The LinearLayout "teste4" is inside "teste3". I need to insert LinearLayout "address2" inside "teste4". Can you tell me what I'm doing wrong?.
I think there is some misunderstanding here about how the findViewById works. I'll try to explain it below. Hope this helps, let me know if it doesn't.
There are two possible findViewById() that can be used.
Activity.findViewById(): this can be used to find a view in the current activity's main content view -- that is, the view that was set using setContentView(). It cannot be used for any other purpose. For example, it cannot find a view from any other layout file -- the function simply would have no way of knowing how to find it. As far as I can tell, this is the function you're trying to use. If the last XML file you have is not the main layout, then the line address2 = (LinearLayout)findViewById(R.id.sfsp2_layout) will fail.
View.findViewById(): this function can be used to find a view that is contained in some other view. E.g. if you have view1 that contains view2, and view2 has ID some_id, then you can find view2 by calling view1.findViewById(R.id.some_id). In order for this to work, view1 has to be fully initialized. E.g. if view1's description is in XML, it has to be fully inflated first.
In essence, if you want to work with a view that is described in a separate XML file, you have to inflate it first. I don't think there is a way around it.

android: reuse a RelativeLayout in XML by inflating it at run time?

Edition of question
It is already in a separate xml (tablet_shortterm_column.xml) see above.
Anyway, it seems logcat complains that rlo_shortterm_col already has a parent, so it won't allow an another ptr_rlo_rght_middle.addView(rlo_shortterm_col ). Makes no sense.
I spent so many hours on thsi problem and still can't solve it. Can someone please give me a hand? Thanks in advance.
I have an xml file (tablet_shortterm_column.xml) that contains a RelativeLayout that I need to re-use, again and again. Sometimes many times on the same screen stacked one after the other horizontally. I am attempting to insert one into an existing RelativeLayout (ie. one inside the other.)
//exerpts
public class TabletMain extends Activity {
setContentView(R.layout.tablet_main);
public RelativeLayout ptr_rlo_rght_middle;
ptr_rlo_rght_middle = (RelativeLayout) findViewById(R.id.rlo_rght_middle);
//rlo_rght_middle is in tablet_main.xml
LayoutInflater inflater =
(LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View llo_tmp = (View) inflater.inflate(R.layout.tablet_shortterm_column,null);
RelativeLayout rlo_tmp = (RelativeLayout) llo_tmp.findViewById(R.id.rlo_shortterm_col);
// rlo_shortterm_col is the object I want to reuse it a RelativeLayout and is inside
// tablet_shortterm_column.xml
RelativeLayout.LayoutParams rlo_layoutparams;
rlo_layoutparams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
rlo_layoutparams.addRule(RelativeLayout.RIGHT_OF, R.id.llo_rght_middle_col1);
// llo_rght_middle_col1 is a RelativeLayout inside tablet_main.xml,
// I want to put another RelativeLayout view right next to it.
rlo_tmp.setLayoutParams(rlo_layoutparams);
ptr_rlo_rght_middle.addView(rlo_tmp); //Application crashes right on this line.
} //end Activity
//********************* content of tablet_shortterm_column.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RelativeLayout
android:id="#+id/rlo_shortterm_col"
android:layout_width="180dp"
android:layout_height="fill_parent"
android:background="#436699"
android:orientation="vertical"
android:layout_margin="3px"
android:weightSum="1"
> <!-- android:background="#32CD32" android:layout_height="365dp" android:layout_margin="30px" -->
<Button
android:id="#+id/btn_shortterm_col"
android:layout_alignParentTop="true"
android:text="Tuesday Afternoon"
android:layout_margin="15px"
android:textSize="12px"
android:textColor="#FFFFFF"
android:layout_width="wrap_content"
android:layout_gravity="center_horizontal"
android:background="#296699"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
> <!--android:background="#32CD32" -->
</Button>
<ImageView
android:id="#+id/iv_shortterm_col"
android:layout_below="#+id/btn_shortterm_col"
android:src="#drawable/tblet_icon14_med"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
><!-- android:src="#drawable/tblet_shape1" android:layout_gravity="center_horizontal" -->
</ImageView>
<TextView
android:id="#+id/tv_shortterm_col1"
android:layout_below="#+id/iv_shortterm_col"
android:text="-10ºC"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10px"
android:background="#DCDCDC"
android:textColor="#000000"
android:textSize="12px"
android:layout_centerHorizontal="true"
> <!-- android:layout_gravity="center_horizontal" -->
</TextView>
<TextView
android:id="#+id/tv_shortterm_col2"
android:layout_below="#+id/tv_shortterm_col1"
android:text="Flurries"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10px"
android:background="#DCDCDC"
android:textColor="#000000"
android:textSize="12px"
android:layout_centerHorizontal="true"
>
</TextView>
<RelativeLayout
android:id="#+id/rlo_shortterm_col_1"
android:layout_below="#+id/tv_shortterm_col2"
android:src="#drawable/tblet_shape2"
android:background="#32CD32"
android:layout_height="113dp"
android:layout_margin="40px"
android:layout_width="125dp"
> <!--android:background="#32CD32" android:orientation="vertical" -->
</RelativeLayout>
</RelativeLayout>
</LinearLayout>
Create a separate xml file for your RelativeLayout and then inflate it as many times as you want.
llo_tmp is the parent view of the RelativeLayout you're trying to reuse. Thus, you can't add it to another ViewGroup and you get that logcat error.
You can remove the LinearLayout stuff from your xml file and inflate the xml file in the same way (though maybe instead of returned View you'd return a RelativeLayout). You shouldn't have to change much of the java code since the reference is still the same.
Or, a quick fix may be to add llo_tmp to your ViewGroup instead of rlo_tmp. Either way, rlo_tmp already has a parent and can't be reused. Since you don't have your layout fill the entire screen width, you probably don't want this.

Categories

Resources