12

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)

Grid

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)

Community
  • 1
  • 1
  • 2
    Are you loading images lazily ? If so, the UI is going to be an ever changing mess as they load and re-layout everything every time. Also, have a look at [StaggeredGridLayoutManager](http://developer.android.com/reference/android/support/v7/widget/StaggeredGridLayoutManager.html) – S.D. Jan 06 '16 at 06:33
  • need cells to be constant and if image big need show in 2 or more cells –  Jan 06 '16 at 06:47
  • Can you describe in more detail what image sizes can occur, when you want to use more than 1 cell and what you want to do if the image does not exactly match with cells (cropping/resizing...)? – user3316041 Jan 06 '16 at 09:43
  • 2
    Do you want something like the [AsymmetricGridView](https://github.com/felipecsl/AsymmetricGridView)? – Adrian C. Jan 06 '16 at 10:08
  • @sreekanth your ans is [AsymmetricGridView](https://github.com/felipecsl/AsymmetricGridView) library – Ravi Jan 06 '16 at 10:20

3 Answers3

10

Without disturbing the grid, the workaround I see is to dynamically set image on top of your TableLayout. Then you can archive this:

enter image description hereenter image description here

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.

Konstantin Loginov
  • 15,802
  • 5
  • 58
  • 95
  • the grid may vary, so everything need to dynamic –  Jan 06 '16 at 10:18
  • @sreekanth that's perfectly fine - just do same trick with dynamic table – Konstantin Loginov Jan 06 '16 at 10:20
  • yes sir, but my requirment is not 2x2 its 10x4 grid on that i have to add some image( 1 cell size images,2 cell size images and 4 cell size image) then i have to drag and drop on grid.....give me some idea on this sir –  Jan 06 '16 at 10:22
  • @sreekanth - idea is same: set width/height based on number of cells you filling and proper margins. About drag-n-drop - I believe, you will need to add some extra listeners to the dynamic ImageView, etc. – Konstantin Loginov Jan 06 '16 at 10:26
1

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.

Viral Patel
  • 32,418
  • 18
  • 82
  • 110
  • yes, was there already. Also posted a brief in the chat about how the above could probably work for what you are trying. – Viral Patel Jan 06 '16 at 11:12
  • if try to increase size of image it disturbing evering...like-http://i.stack.imgur.com/lenEs.png –  Jan 06 '16 at 11:15
  • This should not happen in my suggestion because you are adding the row after adding the image. Also set sizes in the row layouts because already know them and have different predetermined sizes for different layout spans I'm hoping. – Viral Patel Jan 06 '16 at 11:19
  • First note down the types of rows you can have. Create one layout for each row types and then inflate and add table rows dynamically as you need. – Viral Patel Jan 06 '16 at 11:30
  • If the image is same you could as well put its reference and required size in the row layout to avoid resize complications and alignment disruption that happens when resizing it in java code – Viral Patel Jan 06 '16 at 11:31
  • isnt this the same image you shared before? I'd suggest you try this out once and see if you get the expected output – Viral Patel Jan 06 '16 at 11:43
1

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.

rupesh jain
  • 3,410
  • 1
  • 14
  • 22