如何根据大小在表格行中显示图像

12

现有一个 2x2 的网格(使用 TableLayout 动态创建),需要在上面显示图片。根据图片大小,如果适合一个单元格则占用一个单元格,否则如果较大则会占用 2 个或 4 个单元格(我知道它将占用多少个单元格)。

Grid

我可以在一个单元格中显示图片,但问题是如果图片需要 2 个单元格(第一列),如何在 2 个单元格中显示图片(不破坏网格的结构)。


2
你是否正在懒加载图片?如果是这样,UI 将会在每次加载和重新布局时变得混乱不堪。此外,请查看 StaggeredGridLayoutManager - S.D.
需要将单元格设置为常量,如果图像太大,则需要在2个或更多单元格中显示。 - user4302606
你能否更详细地描述一下,当你想使用多个单元格时,可能出现哪些图像尺寸,并且如果图像与单元格不完全匹配,你想要做什么(裁剪/调整大小...)? - user3316041
2
你想要类似于AsymmetricGridView这样的东西吗? - Adrian C.
@sreekanth,你的答案是AsymmetricGridView库。 - Ravi
3个回答

10

在不干扰网格的情况下,我看到的解决方法是将图像动态设置为您的TableLayout上方。 然后您可以实现这个:

enter image description hereenter image description here

我已经上传了测试项目的代码在这里

您需要初始化overlappingImage,当您需要向单元格设置图像时 - 只需将其添加到布局中并设置高度和宽度参数,基于您想要填充的单元格数量。

TableLayout会动态生成单元格的布局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>

Activity的布局:

<?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>

处理按钮点击并生成表格的活动代码:

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);
    }
}

我希望这能帮助到您。


网格可能会变化,所以一切都需要动态。 - user4302606
@sreekanth,那很好-只需对动态表格执行相同的技巧即可。 - Konstantin Loginov
是的先生,但我的要求不是2x2,而是10x4的网格,在上面我需要添加一些图像(1个单元格大小的图像、2个单元格大小的图像和4个单元格大小的图像),然后我需要拖放到网格上...请给我一些想法,先生。 - user4302606
@sreekanth - 想法是一样的:根据您填充的单元格数量和适当的边距设置宽度/高度。关于拖放 - 我相信,您需要为动态ImageView添加一些额外的监听器等。 - Konstantin Loginov

1
为需要一个单元格和两个单元格的行创建单独的布局文件,如下所示: < p > < strong > one_cell_table_row.xml (注意< code > ImageView 的< code > android:layout_span="2" )
<?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.xmlTextView仅作为第二个单元格的占位符)(此布局中不需要像上面布局中那样使用layout_span

<?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>

注意:ImageView的id在两个布局中必须保持一致,以使下面的Java代码正常工作。

上述假设您的网格为2x2。如果您的网格大小不同,请为每种所需行创建更多布局,并在下面的Java代码中添加额外条件。

使用正确的布局填充TableRow

然后程序上确定需要填充哪个布局。填充所需的表格行布局并将其添加到您的表格布局中:

以下代码假设您正在使用一个片段。如果您直接在活动中进行操作,则替换代码以适用于活动。

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();

再次说明,上述假设您的TableLayout具有2x2的网格。如果您打算使用不同的表格布局,请相应地更新我们上面创建的TableRows的布局文件或使用您的Java代码动态设置它们。


是的,已经有了。同时在聊天中发布了一个简要说明,关于上述内容可能如何适用于您正在尝试的情况。 - Viral Patel
如果尝试增加图像的大小,它会扰乱所有东西...就像这样 - http://i.stack.imgur.com/lenEs.png - user4302606
这不应该发生在我的建议中,因为您是在添加图像后添加行的。此外,在行布局中设置大小,因为已经知道它们并且对于不同的布局跨度有不同的预定大小,我希望如此。 - Viral Patel
首先记录下你可以拥有的行类型。为每个行类型创建一个布局,然后根据需要动态地填充和添加表格行。 - Viral Patel
如果图像相同,您可以将其引用和所需大小放入行布局中,以避免在Java代码中调整大小时出现的调整复杂性和对齐破坏。 - Viral Patel
这不是你之前分享的同一张图片吗?我建议你尝试一下,看看是否能得到预期的输出。 - Viral Patel

1
你可以在运行时计算图像大小和屏幕大小。根据计算结果,你可以在运行时设置表格属性。例如,如果图像将占用两列,则可以在该行上以编程方式设置 span 属性。
我建议你考虑在代码中创建布局,而不是使用任何 xml。
你还可以查看 Recycler View。它有更强大的方法来控制子项的布局。观看这个视频- 掌握 Recycler View-它试图做与你所寻找的类似的事情。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接