I have a basic app working, but now I am focusing on formatting the app and running into difficulty laying things out as I want them.
I have a list of images that the user can switch from one to the next with using a next button. Both the images and the next button are added programmatically to the page (I clear out anything in the layout, and then add the ImageView and Button). Now, instead of laying them out one on top of the other, I am trying to lay them out next to each other, so the image will take up most of the space, and then the next button will be to its right.
Looking through the documentation I was leaning towards using a RelativeLayout to accomplish this. However, I ran into some questions while using RelativeLayouts programmatically.
Activity.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true">
<RelativeLayout
android:orientation="vertical"
android:id="#+id/activity_training_package_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.example.xxx.PackageActivity"
tools:ignore="MergeRootFrame">
</RelativeLayout>
</ScrollView>
Attempt to programmatically add the button:
public void addNextButton(final int currentFile, final RelativeLayout layout) {
Button next = new Button(this);
next.setWidth(100);
int id = layout.getChildAt(0).getId(); // the image is the only thing there
RelativeLayout.LayoutParams lay = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lay.addRule(RelativeLayout.RIGHT_OF, id);
next.setLayoutParams(lay);
next.setText("NEXT >>");
next.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
showNextFile(currentFile, layout);
}
//layout.setLayoutParams(lay);
layout.addView(next);
...
I am just wondering which LayoutParams I am supposed to be setting for this, the LayoutParams of the layout, or of the view? When I try to set it to the layout, I get a cast exception (it is expecting a FrameLayout.LayoutParams, not a RelativeLayout.LayoutParams for some reason).
Could someone please point me in the right direction to figure out how layouts are used? I cannot seem to find resources that explain which LayoutParams I should be setting.
TL;DR How do you use RelativeLayouts and LayoutParams programmatically?
The simplest solution is to use the HorizontalSrollView with a LinearLayout.
activity_test.xml
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal" />
</HorizontalScrollView>
TestActivity.java
public class TestActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
LinearLayout container = (LinearLayout)findViewById(R.id.container);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
String next = getResources().getString(R.string.next);
for(int i=0;i<5;i++){
ImageView imgView = new ImageView(mActivity);
imgView.setLayoutParams(params);
imgView.setImageResource(R.drawable.photo);
container.addView(imgView);
Button button = new Button(mActivity);
button.setLayoutParams(params);
button.setText(next);
container.addView(button);
}
}
}
set Linear Layout weight Property in your XML file and assign weight to the imageview and button
main_activity.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:orientation="horizontal"
android:weightSum="1" />
MainActivity.java
package com.example.stackoverflowdemos;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TableLayout;
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout container = (LinearLayout)findViewById(R.id.container);
//Dynamically generate imageview and button
ImageView imgView = new ImageView(this);
imgView.setLayoutParams(new TableLayout.LayoutParams(0, LayoutParams.FILL_PARENT, .2f)); //set imageview height and width using weight
imgView.setImageResource(R.drawable.ic_launcher);
container.addView(imgView);
Button button = new Button(this);
button.setLayoutParams(new TableLayout.LayoutParams(0, LayoutParams.WRAP_CONTENT, .8f)); //set Button height and width using weight
button.setText("next");
container.addView(button);
}
}
Related
I am programming a android app with ImageView and when I try to change the width and height dynamically, the app stops (abort). I am using the following commands:
RelativeLayout.LayoutParams icon_horizontal = new RelativeLayout.LayoutParams(50, 50);
mec21h_icon2.setLayoutParams(icon_horizontal);
The layout is Relative, so what is wrong?
It would be nice to have a Stack trace in order to understand what the error is.
Without this, I can just guess:
you're trying to use the wrong parent layout params
the ImageView ref is null
...
I guess you are trying to change the image dimensions after it is visible (already displayed), if so you should first call for method requestLayout();
i.e.
mImageView.requestLayout();
Re-size image on Click of a button.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/rel"
tools:context="com.testingpp.scannerbarcode.MainActivity">
<ImageView
android:id="#+id/imageview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="button_one"
android:src="#drawable/btn_back"
/>
</FrameLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
FrameLayout layout;
ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.imageview);
layout = (FrameLayout) findViewById(R.id.rel);
}
public void button_one(View view)
{
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(50,50);
layout.setLayoutParams(params);
}
}
if you are using Framents, then don't use onClick of xml. use onClickListener in java.
I want to set textview height and width programmatically which support all screen sizes.
Here is my activity.xml in which I have two LinearLayout. In the second layout I put multiple textview dynamically more than 10 or 12.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:orientation="horizontal"
tools:context="com.example.sagargajera.setballs.MainActivity">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="6">
</LinearLayout>
<LinearLayout
android:id="#+id/layout_balls"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_gravity="center"
android:orientation="horizontal"
android:background="#3F51B5"
android:layout_weight="1">
<!--Here I tried to put layout and inside this layout I want to put textview. -->
</LinearLayout>
</LinearLayout>
Here is my MainActivity.java in which i tried to create layout and textview according to my loop.
package com.example.sagargajera.setballs;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
LinearLayout layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
layout=(LinearLayout)findViewById(R.id.layout_balls);
// DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
// int width = displayMetrics.widthPixels;
// int height = displayMetrics.heightPixels;
for(int i=1;i<=12;i++){
// LinearLayout.LayoutParams param1=new LinearLayout.LayoutParams(width, (height/7));
LinearLayout.LayoutParams param1=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT);
LinearLayout layout_1=new LinearLayout(this);
layout_1.setOrientation(LinearLayout.HORIZONTAL);
layout_1.setLayoutParams(param1);
layout_1.setGravity(Gravity.CENTER);
layout_1.setBackgroundColor(Color.parseColor("#f32f32"));
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(20,20);
param1.weight=1;
TextView tv=new TextView(this);
tv.setGravity(Gravity.CENTER);
tv.setLayoutParams(params);
tv.setText("" + i);
tv.setBackgroundDrawable(getResources().getDrawable(R.drawable.cicle));
tv.setTextColor(Color.parseColor("#FFFFFF"));
layout_1.addView(tv);
layout.addView(layout_1);
}
}
}
Here is my screenshot:
Above code which create layout as well as textview. A Textview is set inside the dynamic layout and dynamic layout is set inside my xml specific layout namely layout_balls.
The problem is when I run this app in small device it give me perfect output but when I run this app in large devices or tablet output was unexpected.
You can get the device density like this:
float scaledDensity = getResources().getDisplayMetrics().scaledDensity;
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(20 * scaledDensity,20 * scaledDensity);
param1.weight=1;
There is some little bit change on below post.
float scaledDensity = getResources().getDisplayMetrics().scaledDensity;
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(20 * scaledDensity,20 * scaledDensity);
param1.weight=1;
The only change is we need to convert float into int so use below:
float scaledDensity = getResources().getDisplayMetrics().scaledDensity;
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(20 * (int)scaledDensity,20 * (int)scaledDensity);
param1.weight=1;//This is the correct answer.
I am trying to add the button dynamically when list is empty i.e no data to populate the list. I tried the below code and it not working
public class TableDemoActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linear);
Button test = new Button(this);
test.setText("Hello Android");
test.setId(5);
test.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
linearLayout.addView(test);
}
}
Here is the layout file contents
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linear"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TableLayout
android:id="#+id/TblLyt"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TableRow
android:id="#+id/AcctHeader"
>
</TableRow>
<ExpandableListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/BankExpandableListView"
android:layout_width="fill_parent"
android:layout_height="443dp"
android:layout_weight="1.32"
>
</ExpandableListView>
</TableLayout>
</LinearLayout>
You can put your button in xml layout file and do visible & invisible as per your condition
if(your condition)
{
button.setVisibility(View.VISIBLE);
}
else
{
button.setVisibility(View.GONE);
}
I solved your problem. Follow these steps. Your code is right but you have made a small mistake. You are adding your view or button in linear layout but your table layout is holding the entire area of your screen by using width and height being fill parent, so just add your button in table layout like this:
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TableLayout;
public class TableDemoActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linear);
TableLayout table=(TableLayout) findViewById(R.id.TblLyt);
Button test = new Button(this);
test.setText("Hello Android");
test.setId(5);
test.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
table.addView(test);
//linearLayout.addView(test);
}
}
Now you can add button dynamically.
It's there, you just can't see it because of this:
<TableLayout
android:id="#+id/TblLyt"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
You are telling table to fill the entire layout. You could set the TableLayout to GONE and then add the button, or you can change the layout_height to wrap_content.
I have created an array of buttons for my app. Now I am not able to manage the layout of these array of buttons. As a result of this, whenever I add image or change width of the buttons it's going out of the horizontal screen of the device. So is there any way to manage these Array of buttons so that they can fit in any screen size.
Here is my code:
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:id="#+id/liVLayout"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</LinearLayout>
<LinearLayout
android:id="#+id/liVLayout1"
android:orientation="vertical"
android:layout_below="#+id/liVLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:text="All Contacts"
android:id="#+id/textView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#android:color/black"
android:background="#808080">
</TextView>
</LinearLayout>
</RelativeLayout>
Java:
public class CalenderForm extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
createCalender();
}
public void createCalender()
{
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams
(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
);
LinearLayout layoutVertical = (LinearLayout) findViewById(R.id.liVLayout);
LinearLayout rowLayout=null;
Button[][] buttons = new Button[6][7];
int count=43;
for (int i = 0; i<6; i++)
{
if(count%7==1)
{
rowLayout = new LinearLayout(this);
layoutVertical.addView(rowLayout,p);
count=count-7;
}
for(int j=0;j<7;j++)
{
buttons[i][j]=new Button(this);
buttons[i][j].setBackgroundResource(R.drawable.icon);
rowLayout.addView(buttons[i][j], p);
}
}
}
}
Snapshot before inserting image:
Snapshot before inserting image:
I know this doesn't directly answer your question, but I just want to help you out. If you're building a calendar app, creating lots of buttons really isn't the way to go:
You will have problems on different ROMs because of skins, etc.
You will not have full control over the layout (again because of the skins)
You will run into spacing issues
You will allocate a lot of memory (lots of Button objects, etc.) which will cause your app to be slow.
What I recommend is implementing your own custom View. I recently worked on a calendar app myself and tried using a GridView for the month, and that really didn't work out well (although it looked like it would), so I ultimately created my own View, which worked out perfect.
What I found very useful was Android's default, open source Calendar app. You'll find source code in there for both a month view and a day / week view (with an hour scale, etc.).
You could try a TableLayout and set the columns wrappable:
Found a nice tutorial with examples -> Android TableLayout Tutorial
To make a column wrappable (to reduce it’s width and wrap it’s content if other columns in the table are taking too much space and pushing some columns off the screen), use setColumnShrinkable to mark it shrinkable.
sounds promising
just replace this code.use weightsum property of linear and layout_weight of buttons.
package com.android.manager;
import android.app.Activity;
import android.os.Bundle;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
createCalender();
}
public void createCalender()
{
LinearLayout layoutVertical = (LinearLayout) findViewById(R.id.liVLayout);
LinearLayout rowLayout=null;
Button[][] buttons = new Button[6][7];
int count=43;
**LayoutParams param = new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT,1);**
for (int i = 0; i<6; i++)
{
if(count%7==1)
{
rowLayout = new LinearLayout(this);
**rowLayout.setWeightSum(7);**
**layoutVertical.addView(rowLayout,param);**
count=count-7;
}
for(int j=0;j<7;j++)
{
buttons[i][j]=new Button(this);
buttons[i][j].setBackgroundResource(R.drawable.icon);
**rowLayout.addView(buttons[i][j],param);**
}
}
}
}
I want to show two views in one activity. If I clicked on button in the first view I want to see the second and other way round.
The views should not have the same size as the screen so I want e.g. to center it, like you see in first.xml.
But if I add the views with
addContentView(mFirstView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
the views are not centered. They are shown at top left.
How can I use the xml settings to e.g. center it?
first.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:background="#drawable/background"
android:layout_gravity="center"
android:minWidth="100dp"
android:minHeight="100dp"
android:paddingBottom="5dp"
>
<LinearLayout android:id="#+id/head"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton android:id="#+id/first_button"
android:src="#drawable/show_second"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#null" />
</LinearLayout>
second.xml same as first.xml but with
<ImageButton android:id="#+id/second_button"
android:src="#drawable/show_first"
... />
ShowMe.java
public class ShowMe extends Activity {
View mFirstView = null;
View mSecondView = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initFirstLayout();
initSecondLayout();
showFirst();
}
private void initFirstLayout() {
LayoutInflater inflater = getLayoutInflater();
mFirstView = inflater.inflate(R.layout.first, null);
getWindow().addContentView(mFirstView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
ImageButton firstButton = (ImageButton)mMaxiView.findViewById(R.id.first_button);
firstButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ShowMe.this.showSecond();
}
});
}
private void initSecondLayout() {
// like initMaxiLayout()
}
private void showFirst() {
mSecondView.setVisibility(View.INVISIBLE);
mFirstView.setVisibility(View.VISIBLE);
}
private void showSecond() {
mFirstView.setVisibility(View.INVISIBLE);
mSecondView.setVisibility(View.VISIBLE);
}}
Hope someone can help.
Thanks
Why don't you use setContentView(R.layout.yourlayout)? I believe the new LayoutParams you're passing in addContentView() are overriding those you defined in xml.
Moreover, ViewGroup.LayoutParams lacks the layout gravity setting, so you would have to use the right one for the layout you're going to add the view to (I suspect it's a FrameLayout, you can check with Hierarchy Viewer). This is also a general rule to follow. When using methods that take layout resources as arguments this is automatic (they might ask for the intended parent).
With this consideration in mind, you could set your layout params with:
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(/* wrap wrap */);
lp.setGravity(Gravity.CENTER);
addContentView(mYourView, lp);
But I would recommend setContentView() if you have no particular needs.
EDIT
I mean that you create a layout like:
~~~/res/layout/main.xml~~~
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="....."
android:id="#+id/mainLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
then in your onCreate() or init...Layout():
setContentView(R.layout.main);
FrameLayout mainLayout = (FrameLayout)findViewById(R.id.mainLayout);
// this version of inflate() will automatically attach the view to the
// specified viewgroup.
mFirstView = inflater.inflate(R.layout.first, mainLayout, true);
this will keep the layout params from xml, because it knows what kind it needs. See reference.