I have a code which generate several ImageView and put it on Layout.
for (int i = 0; i < NUMBER_OF_MATCHES; i++) {
imageView = new ImageView(this);
if (random.nextBoolean()) {
imageView.setImageResource(R.drawable.match);
} else {
imageView.setImageResource(R.drawable.match_inverse);
}
gameLinearLayout.addView(imageView, 0, params);
}
But all images are in one line. I want to place it in two lines. Which layout to use and how to fix code for working correctly?
If I understand correctly, you want 2 seperate rows of images.
So we need a base LinerLayout with a vertical orientation to hold each row, while each row consists of a LinerLayout with a horizontal orientation:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gameLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/row1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" />
<LinearLayout
android:id="#+id/row2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" />
</LinearLayout>
look here for explanation why it is happening:
Place two ImageViews programmatically
and look here for explanation to the last answer in this thread which talking about RelativeLayout Rules:
How to set RelativeLayout layout params in code not in xml
Try out as below:
//LinearLayOut Setup
LinearLayout linearLayout= new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
for (int i = 0; i < NUMBER_OF_MATCHES; i++)
{
//ImageView Setup
ImageView imageView = new ImageView(this);
//setting image resource
if (random.nextBoolean()) {
imageView.setImageResource(R.drawable.match);
} else {
imageView.setImageResource(R.drawable.match_inverse);
}
//setting image position
imageView.setLayoutParams(linearLayout);
//adding view to layout
linearLayout.addView(imageView);
}
Related
I want to generate programmatically Horizontal scrolling LinearLayout with Imageview and textview at center bottom.
this is my Java code.:
LinearLayout rec=(LinearLayout)findViewById(R.id.hori_recom);
//ViewGroup.LayoutParams params=new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ViewGroup.LayoutParams params=new ViewGroup.LayoutParams(450,450);
ViewGroup.LayoutParams params1=new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
// for(int g=0;g<5;g++)
for(int g=0;g<imgpath_orignal.size();g++)
{
ImageView recimg=new ImageView(Details.this);
recimg.setId(g+1);
recimg.setPadding(25,0,0,0);
Picasso.with(Details.this).load(al_gallary_img.get(g)).placeholder(R.drawable.logo)
.error(R.drawable.logo).into(recimg);
recimg.setLayoutParams(params);
TextView txtlabel=new TextView(Details.this);
txtlabel.setId(g+1);
txtlabel.setGravity(Gravity.CENTER|Gravity.BOTTOM);
txtlabel.setPadding(15,15,15,15);
txtlabel.setText(""+al_img_caption.get(g));
txtlabel.setLayoutParams(params1);
rec.addView(txtlabel);
rec.addView(recimg);
This is my Xml:
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/hori_recom"
android:layout_marginTop="10dp"/>
</HorizontalScrollView>
Problem is I am not getting my textview at bottom-center of my Imageview.
Do one thing - combine your ImageView and TextView in one layout
Say this layout as row_layout.
<LinearLayout
....
....
<ImageView
...
... />
<TextView
...
... />
</LinearLayout>
Now add Layout into the LinearLayout which lies into HorizontalScrollView -
for(int g=0; g<imgpath_orignal.size(); g++) {
View v = LayoutInflater.from(context).inflate(R.layout.row_layout, parent, false);
// Do your layout binding stuff over here..
ImageView ivPhoto = (ImageView) v.findViewById(R.id.imageview_id); // Give reference
Picasso.with(context).load(url).into(ivPhoto); // Loading image using Picasso
rec.addView(v);
}
This is because you have set gravity of TextView as center_bottom instead of layout_gravity.
Just remove
txtlabel.setGravity(Gravity.CENTER|Gravity.BOTTOM);
and instead of
ViewGroup.LayoutParams params1 = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);`
do this
LinearLayout.LayoutParams params1 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
params1.gravity = Gravity.CENTER|Gravity.BOTTOM;
This is the way of setting layout_gravity programatically.
Hi I have a ScrollView and a vertical LinearLayout inside that. Inside each LinearLayout slot I have a horizonal LinearLayout that holds 2 things a word and a number. The problem is some of the words are hidden?? and it takes up half the screen. Thanks for any help.
Layout bounds
for (int i = 0; i < words.size(); i++) {
LinearLayout horizontal = new LinearLayout(context);
horizontal.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams LLParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
horizontal.setLayoutParams(LLParams);
btnWord.add(i, new Button(context));
btnWord.get(i).setHeight(60);
btnWord.get(i).setWidth(120);
btnWord.get(i).setTypeface(montFont);
btnWord.get(i).setBackgroundColor(Color.WHITE);
btnWord.get(i).setTag(i);
btnWord.get(i).setGravity(Gravity.CENTER);
btnWord.get(i).setText(" " + words.get(i));
btnWord.get(i).setOnClickListener(btnClicked);
horizontal.addView(btnWord.get(i));
wordWeight.add(i, new Button(context));
wordWeight.get(i).setHeight(60);
wordWeight.get(i).setWidth(40);
wordWeight.get(i).setTypeface(montFont);
wordWeight.get(i).setBackgroundColor(Color.WHITE);
wordWeight.get(i).setTag(i);
wordWeight.get(i).setGravity(Gravity.CENTER);
wordWeight.get(i).setText(" " + wordWeights.get(i));
wordWeight.get(i).setOnClickListener(btnClicked);
horizontal.addView(wordWeight.get(i));
linearLayout.addView(horizontal);
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white">
<ScrollView
android:layout_width="match_parent"
style="#android:style/Widget.ScrollView"
android:layout_marginTop="106dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/linearLayout" />
</ScrollView>
</RelativeLayout>
You could try to set the weight of each "item" to 1 so they will equally divide the space on the screen. Something like the snippet below:
LinearLayout ll;
LinearLayout.LayoutParams lp;
lp.weight = 1;
ll.setLayoutParams(lp);
You could also ditch that logic and use a ListView with a custom adapter like I did on this answer, or setup a RecyclerView as you can see on this blog post. It's way easier and more efficient to do either one of those.
More on ListView vs. RecyclerView here.
I want to add dynamic view into a Horizontal LinearLayout. But my issue is if there is no space at Horizontal it should automatically placed on vertically.
My Image
My Expected Result
My Codes are
for (int j = 0; j < jobDet.getKeywords().length; j++) {
RelativeLayout tr_head = (RelativeLayout) getLayoutInflater().inflate(R.layout.tag_lay, null);
TextView label_date = (TextView) tr_head.findViewById(R.id.tag_name);
label_date.setText(jobDet.getKeywords()[j]);
keywordL.addView(tr_head, new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
}
My "tag_lay.xml"
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="30dp"
android:id="#+id/tag_name"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:background="#drawable/round_edit_box"
android:text=" PHP "
android:gravity="center"
android:lines="1"
android:layout_marginRight="5dp"/>
</RelativeLayout>
You can not do that with single LinearLayout because it has either VERTICAL or HORIZONTAL orientation. I would suggest you to take a look at google's FlexboxLayout. Its a library which provides a layout where you can achieve similar view. You can add this library by adding below line to your app level gradle file:
compile 'com.google.android:flexbox:0.1.3'
You can change the keywordL to FlexboxLayout from LinearLayout. A sample code for container layout can be something like below:
<com.google.android.flexbox.FlexboxLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/flexbox_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:alignContent="flex_start"
app:alignItems="flex_start"
app:flexWrap="wrap"/>
You can change the value of alignContent, alignItems and flexWrap according to your requirement. Although this should work because it is working for me. While adding the childs you can do something like below:
for (int j = 0; j < jobDet.getKeywords().length; j++) {
RelativeLayout tr_head = (RelativeLayout) getLayoutInflater().inflate(R.layout.tag_lay, keywordL, false );
TextView label_date = (TextView) tr_head.findViewById(R.id.tag_name);
label_date.setText(jobDet.getKeywords()[j]);
keywordL.addView(tr_head);
}
Please let me know if you have trouble implementing.
Have 2x2 grid(Dynamic using TableLayout) need to show image on that. now based on image size, means-- if image fit for 1 cell means 1 cell,else big means 2 cells or 4 cells based on size( I know how many cells it will occupy)
i can show image in 1 cell, but problem is if image need 2 cells(1st column) how can show image in 2cell(With out disturbing the grid)
Without disturbing the grid, the workaround I see is to dynamically set image on top of your TableLayout.
Then you can archive this:
I've uploaded the code of the test project here;
You initialize overlappingImage and once you need to set image to your cell - you just add it to the layout and setting height and width params based on number of cells you want to fill.
TableLayout generates dynamically, the cell's layout xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
<View
android:layout_margin="4dp"
android:background="#aacc00"
android:layout_height="40dp"
android:layout_width="40dp"/>
</FrameLayout>
The Activity's layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/container"
android:padding="16dp"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<TableLayout
android:id="#+id/tableLayout"
android:layout_width="match_parent"
android:layout_height="280dp"/>
<LinearLayout
android:id="#+id/buttonsLinearLayout"
android:layout_below="#+id/tableLayout"
android:layout_marginTop="16dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:text="1x1"
android:id="#+id/button11"
android:onClick="onClick11"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:text="4x1"
android:id="#+id/button21"
android:onClick="onClick41"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:text="2x3 at (2;2)"
android:id="#+id/button12"
android:onClick="onClick32"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:text="2x2"
android:id="#+id/button22"
android:onClick="onClick22"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</RelativeLayout>
And the Activity code to handle button clicks & generates table:
public class MainActivity extends AppCompatActivity {
RelativeLayout container;
int cellWidth = 0, cellHeight = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
tableLayout.setStretchAllColumns(true);
for (int i = 0; i < 4; i++) {
TableRow tableRow = new TableRow(this);
for (int j = 0; j < 10; j++) {
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View cell = layoutInflater.inflate(R.layout.table_cell, null, false);
if (cellHeight == 0 ) {
cell.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
cellWidth = cell.getMeasuredWidth();
cellHeight = cell.getMeasuredHeight();
}
tableRow.addView(cell);
}
tableLayout.addView(tableRow);
}
container = (RelativeLayout)findViewById(R.id.container);
overlappingImage = new ImageView(this);
overlappingImage.setScaleType(ImageView.ScaleType.FIT_XY);
}
ImageView overlappingImage;
private void restoreTableLayout() {
container.removeView(overlappingImage);
}
public void onClick11(View view) {
restoreTableLayout();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(cellWidth, cellHeight);
overlappingImage.setLayoutParams(params);
overlappingImage.setImageResource(R.drawable.horizontal_cat);
container.addView(overlappingImage);
}
public void onClick41(View view) {
restoreTableLayout();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(cellWidth*4, cellHeight);
overlappingImage.setLayoutParams(params);
overlappingImage.setImageResource(R.drawable.horizontal_cat);
container.addView(overlappingImage);
}
public void onClick32(View view) {
restoreTableLayout();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(cellWidth*3, cellHeight*2);
params.setMargins(cellWidth*2, cellHeight*2, 0 ,0);
overlappingImage.setLayoutParams(params);
overlappingImage.setImageResource(R.drawable.vertical_cat);
container.addView(overlappingImage);
}
public void onClick22(View view) {
restoreTableLayout();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(cellWidth*2, cellHeight*2);
overlappingImage.setLayoutParams(params);
overlappingImage.setImageResource(R.drawable.horizontal_cat);
container.addView(overlappingImage);
}
}
I hope, it helps.
Create separate layout files for rows that would need one cell and two cell as follows:
one_cell_table_row.xml (Notice the android:layout_span="2" for the ImageView
<?xml version="1.0" encoding="utf-8"?>
<TableRow
android:background="#drawable/bg_gray"
android:layout_marginTop="5dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:id="#+id/imgMyImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_span="2" />
</TableRow>
two_cell_table_row.xml (The TextView placed just as a placeholder for the second cell) (No layout_span required here as in the above layout)
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:id="#+id/imgMyImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_weight="1"
android:text="..."
android:textColor="#767575"
android:id="#+id/txtJustAPlaceholder"
android:textSize="14dp" />
</TableRow>
Note: The id for the ImageView to be kept same in both layout for the java code below to work correctly.
The above is assuming your grid is 2x2. If your grid size is different create more layout for each kind of row you want and add extra conditions in the java code below.
Adding the TableRow with the right layout inflated:
Then programatically determine which layout needs to be inflated. Inflate the required layout for table row and add it to your table layout:
Following code is assuming that you are using a fragnemt. If you are doing directly in an activity replace code to work for Activity accordingly.
TableLayout table = (TableLayout) getView().findViewById(R.id.youtTableLayout);
if(<your image size needs two cells>) {
TableRow row = (TableRow) LayoutInflater.from(getActivity().getApplicationContext())
.inflate(R.layout.two_cell_table_row, null);
}
else if(<your image size needs one cell) {
TableRow row = (TableRow) LayoutInflater.from(getActivity().getApplicationContext())
.inflate(R.layout.one_cell_table_row, null);
}
...
...
// add more conditions and respective layouts as you need.
...
...
ImageView myImgView = (ImageView) row.findViewById(R.id.txtCrdSectionHeader);
// set the image for your image view here.
table.addView(row);
table.requestLayout();
Again, the above was assuming that your TableLayout has a 2x2 grid. If you plan to use a different one, update the layout files for TableRows we created above accordingly or set them dynamically using your java code.
You can calculate the image size and the screen size at runtime.Based on the calculations you can set the table properties at runtime. For example if the image is going to take two columns set the span property on that row programmatically.
I would suggest for your requirement you can consider creating the layout in code itself-rather than using any xml.
You can also have a look at Recycler view. It has more powerful ways to control the layout of the children. Have a look at this video-Mastering Recycler View -It is trying to do similar thing what you are looking for.
I am using a TableLayout in my application. It contains four TableRows each containing four ImageViews. The behavior I want is to scale the layout to fit the shortest dimension.
It works fine in portrait mode but fails miserably in landscape mode.
From the documentation it looks like this is because the TableRow layout_height is always set to WRAP_CONTENT. While I can set the dimensions of the individual Views, the TableLayout won't render at all if I set the View layout_height to FILL_PARENT.
I feel like there is something simple I am missing. Is there a way to get the TableLayout with TableRows to scale to fit the height in landscape mode?
XML Layout:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/table"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:shrinkColumns="*">
</TableLayout>
Java:
public class Example extends Activity {
private TableLayout mTable;
private int[] mDrawableIds = { R.drawable.draw01, R.drawable.draw02, R.drawable.draw03, R.drawable.draw04, R.drawable.draw05, R.drawable.draw06, R.drawable.draw07, R.drawable.draw08, R.drawable.draw09, R.drawable.draw10, R.drawable.draw11, R.drawable.draw12, R.drawable.draw13, R.drawable.draw14, R.drawable.draw15, R.drawable.draw16 };
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTable = (TableLayout)findViewById(R.id.table);
for (int j=0; j<4; j++) {
TableRow tr = new TableRow(this);
tr.setLayoutParams(new ViewGroup.LayoutParams( LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
for (int i=0; i<4; i++) {
ImageView iv = new ImageView(this);
iv.setImageResource(mDrawableIds[j*4+i]);
iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
iv.setAdjustViewBounds(true);
tr.addView(iv);
}
mTable.addView(tr);
}
}
}
Change your XML layout to:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/table"
android:layout_width="fill_parent"
android:layout_height="160dp"
android:shrinkColumns="*">
</TableLayout>
That should make it take up whole screen's height regardless of orientation. See density independent pixels
I did figure out how to do this. Basically, the part that wasn't working the way I wanted was the TableRows. When I changed to landscape, the first two TableRows weren't resizing at all and the third was consuming the remainder of the space. The fourth row wasn't displaying at all.
I figured out that I needed to set the layout_weight of the TableRows to equal values. But, there is no method to do that at runtime, so I built the following layout file, which I called row.xml:
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/trow"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1">
</TableRow>
Then I used a LayoutInflater to build the row at runtime with the properties I wanted:
mTable = (TableLayout)findViewById(R.id.table);
LayoutInflater inflater = getLayoutInflater();
for (int j=0; j<4; j++) {
View row = inflater.inflate(R.layout.row, mTable,false);
TableRow tr = (TableRow)row.findViewById(R.id.trow);
for (int i=0; i<4; i++) {
View image = inflater.inflate(R.layout.image, tr, false);
ImageButton ib = (ImageButton)image.findViewById(R.id.image);
ib.setAdjustViewBounds(true);
ib.setImageResource(mCardIds[j*4+i]);
tr.addView(ib);
}
mTable.addView(tr);
}
Now the TableRows are resizing properly on rotation. I changed the ImageViews to ImageButtons because I decided to add some onClick behavior and I am building those buttons via a separate xml file, but I don't think those details are relevant to the resizing issue.
I tried the accepted solution here but it did not work. What worked is as below:
TableRow tr = new TableRow(this);
TableLayout.LayoutParams pRowTop = new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT);
pRowTop.weight = 1;
mTable.addView(tr, pRowTop);