Building custom card view programmatically - android

I've got problem with creating custom view programmatically.
I wrote something like:
public class TimerCardView extends CardView {
private LinearLayout horizontalContentLayout;
private TextView timeTextView;
public TimerCardView(Context context, AttributeSet attrs) {
super(context, attrs);
horizontalContentLayout = new LinearLayout(context);
LinearLayout.LayoutParams horizontalContentXLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
horizontalContentXLayoutParams.gravity = Gravity.CENTER;
horizontalContentLayout.setLayoutParams(horizontalContentXLayoutParams);
this.addView(horizontalContentLayout);
timeTextView = new TextView(context);
timeTextView.setTextColor(Color.parseColor("#A3A3A3"));
timeTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 40);
timeTextView.setText("0:00:00");
this.horizontalContentLayout.addView(timeTextView);
}
}
and in xml I added:
<com.example.paciu.belmondo.ViewsExtends.TimerCardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
card_view:cardCornerRadius="2dp"
card_view:cardElevation="2dp"
android:layout_margin="4dp">
</com.example.paciu.belmondo.ViewsExtends.TimerCardView>
And the problem is that my text view isn't centered on the screen in the layout. It still stays to the left. But when I added firstly to the xml the same (but the whole in xml):
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
card_view:cardCornerRadius="2dp"
card_view:cardElevation="2dp"
android:layout_margin="4dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="40sp"
android:text="sdasdasd"
android:textColor="#AAAAAA" />
</LinearLayout>
</android.support.v7.widget.CardView>
What am I doing wrong? Thank you for your help!

CardView extends the FrameLayout class. The layout_gravity attribute lands on the FrameLayout.LayoutParams, not on the view horizontalContentLayout. For setting gravity like in your XML use something like:
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT, Gravity.CENTER);
this.addView(horizontalContentLayout,params);

Related

Problems inflating a custom LinearLayout into a custom class that extends LinearLayout

I'm trying to inflate a LinearLayout containing a few different Textviews and a Button into a custom class that extends LinearLayout.
Here is the XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
android:background="#173BBC"
android:gravity="center_vertical"
android:minWidth="200dp"
android:minHeight="40dp"
android:orientation="horizontal"
android:padding="10dp"
android:visibility="visible">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/textView12"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/compte" />
<TextView
android:id="#+id/textViewCompteT"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/textView14"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/valeur" />
<TextView
android:id="#+id/textViewValeurT"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView" />
</LinearLayout>
</LinearLayout>
<Button
android:id="#+id/buttonDeleteTransaction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawableTop="#android:drawable/ic_menu_delete"
android:minWidth="48dp"
android:paddingLeft="30dp"
android:paddingTop="10dp"
android:paddingRight="30dp"
android:paddingBottom="0dp"
android:textSize="0sp"
app:cornerRadius="20dp"/>
</LinearLayout>
And here is my class: (please don't take care about the names of the variables, they are bad ;) )
public class TransactionTwo extends LinearLayout {
private Context context;
private LinearLayout container;
private LinearLayout content;
private LayoutParams layoutParams;
private LayoutParams contentLayoutParams;
public TransactionTwo(Context context, Activity parent){
super(context);
activity = (Details) parent;
//here i define my layouts to make them have the fine shape.
layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(10, 10, 10, 10);
contentLayoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
this.setLayoutParams(layoutParams);
this.setOrientation(LinearLayout.VERTICAL);
this.setBackgroundColor(Color.RED);
container = new LinearLayout(context);
container.setOrientation(LinearLayout.VERTICAL);
container.setLayoutParams(contentLayoutParams);
}
public void createViews(){
//here i try to force the display of the inflated layout (which doesn't appear on screen)
content = (LinearLayout) inflate(context, R.layout.modele_transaction2, container);
content.setVisibility(View.VISIBLE);
content.setLayoutParams(contentLayoutParams);
container.setMinimumHeight(100);
this.addView(container);
//then i find a few textviews and set their text (which works correctly even if i can't see it)...
}
#Override
protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
}
Everything seems to work correctly (at least Android doesn't raise any error), but the only trouble is that I can see the LinearLayout "TransactionTwo" having the size of the LinearLayout that I inflate in it, but I can't see the inflated one... And when I ask for the height of content and container it always answer 0. So it is as if the inflated layout was only giving its size without appearing...
If anyone knows what is wrong in my code, that would be really appreciated because I'm stucked on this issue for a long time now ;)
Thank you!
In fact it might have been a bug of Android Studio, because I made a copy of my java class and it worked this time...

FrameLayout does not display correct width

I have a layout like below ( to play media files ) :
<?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">
<LinearLayout
android:id="#+id/mediabar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="#+id/btnPlay"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="0.2"
android:text="P">
</Button>
<SeekBar
android:id="#+id/sbProgress"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center"/>
<TextView
android:id="#+id/txtTimeleft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00:00:00"
android:textSize="13sp"
android:paddingRight="10dp"/>
</LinearLayout>
</LinearLayout>
I use a class called CustomView which inherits from FrameLayout to contains the above layout.
public class CustomView extends FrameLayout
Then I will add the above layout to the CustomView on startup :
private void initItems(){
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = null;
rowView = inflater.inflate(R.layout.shadow_layout,null,false);
btnPlay = rowView.findViewById(R.id.btnPlay);
seekBar = rowView.findViewById(R.id.sbProgress);
tvTime = rowView.findViewById(R.id.txtTimeleft);
//scriptFrame = (LinearLayout) rowView.findViewById(R.id.scriptframe);
this.addView(rowView);
setUpFont();
}
And finally, in my activity, I will create and add the above class to my view like this :
shadowingView = new CustomView(context);
shadowingView.setLayoutParams(
new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
scrollView.addView(shadowingView);
But the result is not what I expected, the layout wasn't MATCH_PARENT (Play button's text is not displaying also) :
Please point me where I did wrong. Thank you!
you miss the android:weightSum attribute in your linearlayout
<LinearLayout
//put the weightSum here
android:id="#+id/mediabar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="#+id/btnPlay"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="0.2"
android:text="P">
</Button>
<SeekBar
android:id="#+id/sbProgress"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.6"
android:layout_gravity="center"/>
<TextView
android:id="#+id/txtTimeleft"
android:layout_width="0dip"
android:layout_weight="0.2"
android:layout_height="wrap_content"
android:text="00:00:00"
android:textSize="13sp"
android:paddingRight="10dp"/>
</LinearLayout>
here is the result :
your xml code is working fine here......
SHow me the code of
<FrameLayout
......
......
/>
There might be some error in it.....
try using
shadowingView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT));
Thanks for the answers guys. Unfortunately none of the answers worked. But I have fixed the problem.
For some unknown reason, the scrollview is the problem, all I have to do is change from FrameLayout to ScrollView
public class CustomView extends ScrollView
And here :
shadowingView = new CustomView(context);
shadowingView.setLayoutParams(
new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
// scrollView.addView(shadowingView); REMOVE THIS LINE
// topParent.addView(scrollView); AND THIS LINE
topParent.addView(shadowingView)

LinearLayout does not expand when adding edittext programmatically

So I am trying to add EditText to LinearLayout programmatically. I have added a '+' ImageButton on whose click, I will add an EditText until there are five. Below is a snippet of my XML file.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/margin_16"
android:orientation="horizontal">
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
</LinearLayout>
<ImageButton
android:id="#+id/add_field"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginBottom="#dimen/margin_16"
android:background="#drawable/cyan_top_rounded"
android:src="#drawable/add" />
</LinearLayout>
The LinearLayout with id "Container" will have EditText as child. Below is my code for adding EditText.
mAddField.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (count < 5) {
mAddField.setEnabled(true);
mContainer.addView(getTextField());
count++;
} else {
mAddField.setEnabled(false);
}
}
});
private EditText getTextField() {
EditText et = new EditText(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
et.setLayoutParams(params);
et.setText("abcd");
return et;
}
private void initUI() {
mAddField = (ImageButton) findViewById(R.id.add_field);
mContainer = (LinearLayout) findViewById(R.id.container);
EditText et = new EditText(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
et.setLayoutParams(params);
et.setText("abcd");
mContainer.addView(et);
}
However, when I click on the ImageButton, nothing happens. If the EditText is added at all, the LinearLayout also does not expand. Please help.
Try this:
...
<LinearLayout
android:id="#+id/container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
</LinearLayout>
...
Change ur layout to this it will work fine:(Make the necessary changes according to ur own). Problem is with the height and width of the outer as well as the inner LinearLayout.
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
</LinearLayout>
<ImageButton
android:id="#+id/add_field"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="#drawable/image" />
</LinearLayout>
The view in which you what to add your Edittext dynamically,you have to set it width and height as "wrap_content". So just change your internal layout to :
<LinearLayout
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
I think this will help you out.

How to change the margin of an "included" layout programatically

I have a LinearLayout inside which I am including a different layout. Something like this
<LinearLayout
android:id="#+id/linear_layout"
android:layout_width="match_parent"
android:layout_height="20dp"
android:visibility="gone"
tools:visibility="visible">
<include
layout="#layout/new_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginBottom="4dp"
android:layout_marginLeft="4dp"
android:layout_marginStart="4dp"
android:layout_weight="1"/>
</LinearLayout>
Now what I would like to do is, to programmatically change the "marginBottom" of the included layout (new_layout). How can I do that?
I tried calling various LayoutParams and tried changing the margin, but not sure if it is the right approach. Any help greatly appreciated.
Thanks
Try this.. Make the Linear layout using your id
LinearLayout ll =(LinearLayout) findViewById(R.id.linear_layout);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, 20);
layoutParams.setMargins(left,top,right,bottom);
where you can pass the value in setMargins
and if you want to input value in dp.. Try this
public void setMargin(Context con,ViewGroup.LayoutParams params,int dp) {
final float scale = con.getResources().getDisplayMetrics().density;
// convert the DP into pixel
int pixel = (int)(dp * scale + 0.5f);
ViewGroup.MarginLayoutParams s =(ViewGroup.MarginLayoutParams)params;
s.setMargins(pixel,pixel,pixel,pixel);
yourView.setLayoutParams(params);
}
where you can pass your layout params
include.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:id="#+id/include_layout">
<ImageView android:layout_width="90dp"
android:layout_height="90dp"
android:src="#drawable/cross" />
</LinearLayout>
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<include layout="#layout/include"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello"
android:padding="10dp" />
</LinearLayout>
MainActivity.class
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
LinearLayout included=(LinearLayout)findViewById(R.id.include_layout);
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
params.setMargins(Math.round(10), Math.round(10), Math.round(10), Math.round(10));
//set margin...
included.setLayoutParams(params);
}
}
You should not directly change or modify margins in the <include> tag. This tag is just adding the layout resource in the current view hierarchy without adding an extra parent view container.
So essentially what you want to do is set margins on the root view container of the "included layout". That is you should directly call findViewById() for the root view and set all of your margins on it pro grammatically and as the included view's parent is a Linear-layout you should use
LinerLayout.LayoutParams params = (LinerLayout.LayoutParams) includedRootView.getLayoutParams();
params.setMargins();
includedViewRoot.setLayoutParams(params);`
You can change it by dimensions also
res/values/dimens.xml
res/values-small/dimens.xml
res/values-normal/dimens.xml
res/values-xlarge/dimens.xml
I think this code helpful...
include.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"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" >
</ImageView>
</LinearLayout>
activity_main.xml
<LinearLayout 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" >
<include
android:id="#+id/include_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="4dp"
android:layout_marginStart="4dp"
layout="#layout/include" />
</LinearLayout>
MainActivity
package com.example.stackdemo;
import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;
public class MainActivity extends Activity {
LinearLayout include_layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
include_layout = (LinearLayout) findViewById(R.id.include_layout);
#SuppressWarnings("deprecation")
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
layoutParams.setMargins(0, 0, 0, 100);
include_layout.setLayoutParams(layoutParams);
}
}

How to add to the layout compound component programmatically Android?

I created a compound component Box which I want to add to the layout. Box xml:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayoutForBlock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" android:background="#drawable/screen_background" android:layout_marginLeft="5dp" android:layout_marginTop="5dp">
<ImageButton
android:id="#+id/imageButtonContent"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center_horizontal"
android:scaleType="fitCenter"
android:src="#drawable/beach_bed" android:background="#drawable/buttonbackground" android:clickable="true" android:layout_margin="5dp" android:contentDescription="#string/sample_text"/>
<TextView
android:id="#+id/textViewContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="#string/sample_text"
android:textColor="#color/deep_blue" android:layout_margin="5dp"/>
</LinearLayout>
</merge>
Box class:
public class Box extends LinearLayout {
private TextView textContent;
private ImageView imageContent;
public Box(Context context, AttributeSet attrs) {
super(context, attrs);
((Activity)getContext()).getLayoutInflater().inflate(R.layout.box, this);
setupViewItems();
}
private void setupViewItems() {
textContent = (TextView) findViewById(R.id.textViewContent);
imageContent = (ImageView) findViewById(R.id.imageButtonContent);
}
public void setTextContent(String text) {
this.textContent.setText(text);
}
public void setImageContent(String tag) {
this.imageContent.setContentDescription(tag);
}
}
Everything works if I add the Box to the main xml file like:
<com.mypackage.alexey.Box
android:id="#+id/mybox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
/>
The problem is that I'd like to create many of boxes programmatically something like this: Box mybox= new Box();. How to do it?
I would suggest you also implement the constructors of the LinearLayout that takes only a Context:
public Box(Context context) {
super(context);
}
Then in your Activity, when you want to add a new Box, instantiate the Box class and add it to your layout:
// I assumed you have a LinearLayout to which you want to add your Box
LinearLayout parent = (LinearLayout) findViewById(R.id.parent_id);
//create the Box and added to the parent above
Box theBox = new Box(this); // if you are in an Activity
//some LayoutParams to replicate your xml attributes
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
// set the Orientation for the Box
theBox.setOrientation(LinearLayout.HORIZONTAL);
//add the Box
parent.addView(theBox);

Categories

Resources