Hello i am trying to make a design of chess board, I am using GridLayout containing buttons that corresponds to blocks of the boards. But the layout is so much bigger that it is not fitting the screen, how can i reduce the button size so that the layout fits the screen.
here is the code
public class BoardActivity extends AppCompatActivity {
private GridLayout mBoard;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_board);
mBoard = (GridLayout)findViewById(R.id.board_grid);
addItems();
}
public void addItems(){
int index = 0;
Button button;
for(int i = 0; i < 8; i++){
for(int j = 0; j < 8; j++){
button = new Button(this);
button.setId(index);
button.setPadding(0,0,0,0);
button.setText(""+index);
mBoard.addView(button);
index++;
}
}
}
}
and below is the xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context="com.example.harsh.chessgame.BoardActivity">
<GridLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:rowCount="8"
android:columnCount="8"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:layout_marginBottom="0dp"
android:layout_marginTop="0dp"
android:id="#+id/board_grid">
</GridLayout>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/test_text"/>
</LinearLayout>
and the screenshot of the problem is below
Please help, sorry for mistakes and thanks for help.
In your code you have created Buttons programmatically and you haven't specified any width or height for them. You can add the below line in your code and the width and height will be adjusted.
button.setLayoutParams(new LinearLayout.LayoutParams(100, 100));
But for implementing a chess game, I you should better create a custom adapter for the gridview and images for black and white boxes should be inflated. Anyway for your current try this would help you.
Note: The width and height are just a random number currently given as 100.
Related
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 have problems with setting margin to a custom made linear layout class that I use multiple times in a GridLayout. The Gridlayout is placed in a fragment.
This is the code of fragment_grid.xml:
<FrameLayout 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"
tools:context="app_a_tize.expressme.Fragment.GridFragment"
android:layout_gravity="center">
<GridLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/orange"
android:layout_margin="5dp"
android:id="#+id/gridlayout_grid"></GridLayout>
</FrameLayout>
This is the code of the GridFragment.java:
public class GridFragment extends Fragment {
public GridFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_grid, container, false);
}
#Override
public void onStart() {
super.onStart();
GridLayout grid = (GridLayout) getView().findViewById(R.id.gridlayout_grid);
grid.setRowCount(3);
int tileHeight = (CategoryTileActivity.gridContentHeight -3 * 10) / 3;
int amountofColumns = (int) CategoryTileActivity.gridContentWidth / tileHeight;
grid.setColumnCount(amountofColumns);
grid.setMinimumWidth((amountofColumns * tileHeight) + (5 * 20 ));
for (int i = 0; i < 3 * amountofColumns; i++) {
//fill the grid with the custom LinearLayout:
grid.addView(new TileClass(getActivity(), tileHeight, tileHeight, "ToBeImplemented", "Button"));
}
}
}
This is the code of the custom LinearLayout:
public class TileClass extends LinearLayout {
public TileClass(Context context, int height, int width, String image, String text) {
super(context);
this.setBackgroundResource(R.drawable.tile_button); //creates rounded layouts
this.setMinimumHeight(height);
this.setMinimumWidth(width);
this.setOrientation(LinearLayout.VERTICAL);
ImageView tileImage = new ImageView(context);
Bitmap bMap = BitmapFactory.decodeResource(getResources(), R.drawable.tilephoto);
Bitmap bMapScaled = Bitmap.createScaledBitmap(bMap, 100, 100, true);
tileImage.setImageBitmap(bMapScaled);
tileImage.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
TextView tileText = new TextView(context);
tileText.setText(text);
tileText.setTextColor(Color.WHITE);
tileText.setGravity(Gravity.CENTER);
addView(tileImage);
addView(tileText);
}
}
When I run the Activity, I get this as result:
The code I showed above is responsible for the orange area in the middle. What I need: the blue "buttons"/LinearLayouts, in the orange area in the middle, to have a margin of 5dp. So the rest of the orange space is be taken by the custom LinearLayouts.
I don't know how to fix that, I tried a lot of options but they don't seem to work out for me.. Everything from MarginLayoutParams to params.setMargins(5,5,5,5); On almost every layout in my code.
I use Android Studio 2.1.2, supporting minimum of API 15.
Every help is appreciated!
For your imagination, this must be the end result, I need the margin like this:
You have to make custom view of gridview item as below:-
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="#dimen/categoryHeight"
android:layout_marginLeft="#dimen/margin_5dp"
android:layout_marginRight="#dimen/margin_5dp"
android:layout_marginTop="#dimen/margin_7dp"
android:background="#drawable/rounded_bg"
>
<ImageView
android:id="#+id/llRowItem"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:scaleType="fitXY"
android:gravity="bottom"/>
<TextView
android:id="#+id/item_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/black_light"
android:padding="#dimen/margin_5dp"
android:layout_gravity="bottom"
android:singleLine="true"
android:textColor="#color/white"
android:textSize="#dimen/font_size_16sp" />
</FrameLayout>
and inside adapter set color of text view, background, text or image of imageview whatever you want to set.
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 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);
}
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);**
}
}
}
}