如何在android java中将多个gridviews添加到scrollview? [英] How to add multiple gridviews to a scrollview in android java?

查看:30
本文介绍了如何在android java中将多个gridviews添加到scrollview?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在运行时将多个网格视图添加到线性布局的滚动视图中.但只显示第一行.请帮忙

I'm trying to add multiple gridviews to a scrollview in linear layout at runtime. But only first row displays. Pls help

推荐答案

您不能在 Android 中嵌套可滚动视图 - 即 ListView、GridView、ScrollView.

You can't nest scrollable Views in Android - i.e. ListView, GridView, ScrollView.

你可以看看下面的代码:

You could give a look at the following code:

import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.GridView;

public class ScrollableGridView extends GridView {
    boolean expanded = true;

    public ScrollableGridView(Context context)
    {
        super(context);
    }

    public ScrollableGridView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    public ScrollableGridView(Context context, AttributeSet attrs,
            int defStyle)
    {
        super(context, attrs, defStyle);
    }

    public boolean isExpanded()
    {
        return expanded;
    }


    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        // HACK! TAKE THAT ANDROID!
        if (isExpanded())
        {
            // Calculate entire height by providing a very large height hint.
            // But do not use the highest 2 bits of this integer; those are
            // reserved for the MeasureSpec mode.
            int expandSpec = MeasureSpec.makeMeasureSpec(
                    Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, expandSpec);

            ViewGroup.LayoutParams params = getLayoutParams();
            params.height = getMeasuredHeight();
        }
        else
        {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    public void setExpanded(boolean expanded)
    {
        this.expanded = expanded;
    }
}

它是 GridView 的一个更好的版本,当它嵌套在 ScrollView 中时,它几乎可以工作.我说几乎可以工作",因为我发现有时 20-30 像素太短或太长.您应该注意,这会阻止视图被重用,因此它比普通的 GridView 重得多.

It is a little better version of GridView allowing it to almost work when nested in ScrollView. I said "almost work" since I found it sometimes being 20-30 pixels too short or too long. You should note that this would prevent the views from being reuse, so it is way heavier than normal GridView.

就我而言,我最终扩展了 LinearLayout 并使用它在列中对齐其子项.这并不难——如果你愿意,我可以给你举个例子.:)

In my case I ended up extending LinearLayout and using it to align its children in columns. It wasn't really hard - I can give you examples if you want. :)

我从 这个答案 中得到了 GridView 示例.

I got the GridView example from this answer.

以下是基于 LinearLayout 的 GridView 示例:

Here is an example for a GridView based on LinearLayout:

import java.util.List;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

public class GridLikeLayout extends LinearLayout {
    private static final int DEFAULT_ITEMS_PER_ROW = 1;
    private final int DEFAULT_COLUMN_WIDTH = (int) TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP, 150, getContext().getResources()
                    .getDisplayMetrics());

    private int itemsPerRow = DEFAULT_ITEMS_PER_ROW;
    private List<View> innerViews = null;

    private int columnWidth;

    public GridLikeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.GridLikeLayout);

        // itemsPerRow = a.getInt( R.styleable.GridLikeLayout_columns,
        // DEFAULT_ITEMS_PER_ROW);

        try {
            columnWidth = (int) a.getDimension(
                    R.styleable.GridLikeLayout_column_width, DEFAULT_COLUMN_WIDTH);
        } catch (UnsupportedOperationException uoe) {
            columnWidth = (int) a.getInt(
                    R.styleable.GridLikeLayout_column_width, DEFAULT_COLUMN_WIDTH);
        }

        setOrientation(LinearLayout.VERTICAL);
    }

    public GridLikeLayout(Context context) {
        super(context);
        setOrientation(LinearLayout.VERTICAL);
    }

    public void setInnerViews(List<View> innerViews) {
        this.innerViews = innerViews;
        processViews();
    }

    public List<View> getInnerViews() {
        return innerViews;
    }

    protected void processViews() {
        if (null != innerViews) {
            LinearLayout innerContainer = null;
            innerContainer = generateInnerContainer();
            int childrenCount = innerViews.size();
            for (int index = 0; index < childrenCount; ++index) {
                if (isFull(innerContainer)) {
                    addInnerContainer(innerContainer);
                    innerContainer = generateInnerContainer();
                }
                View child = innerViews.get(index);
                if (null != child.getParent()) {
                    ((ViewGroup) child.getParent()).removeView(child);
                }
                addInnerView(innerContainer, child);
            }

            addInnerContainer(innerContainer);
        }
    }

    protected boolean isFull(LinearLayout innerContainer) {
        return 0 == (innerContainer.getChildCount() % itemsPerRow)
                && 0 < innerContainer.getChildCount();
    }

    protected void addInnerView(LinearLayout innerContainer, View child) {
        int width = LayoutParams.WRAP_CONTENT;
        int height = LayoutParams.WRAP_CONTENT;
        LayoutParams innerParams = new LayoutParams(width, height);
        innerParams.weight = 1;
        innerParams.gravity = Gravity.CENTER;
        innerContainer.addView(child, innerParams);
    }

    protected void addInnerContainer(LinearLayout innerContainer) {
        LayoutParams params = generateDefaultLayoutParams();
        params.width = LayoutParams.MATCH_PARENT;
        addView(innerContainer, params);
    }

    protected LinearLayout generateInnerContainer() {
        LinearLayout innerContainer;
        innerContainer = new LinearLayout(getContext());
        innerContainer.setGravity(Gravity.CENTER);
        return innerContainer;
    }

    public void setOnInnerViewClickListener(OnClickListener listener) {
        for (View innerView : innerViews) {
            innerView.setOnClickListener(listener);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // Sets up mListPadding
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);

        if (widthMode == MeasureSpec.UNSPECIFIED) {
            if (columnWidth > 0) {
                widthSize = columnWidth + getPaddingLeft() + getPaddingRight();
            } else {
                widthSize = getPaddingLeft() + getPaddingRight();
            }
            widthSize += getVerticalScrollbarWidth();
        }

        int childWidth = widthSize - getPaddingLeft() - getPaddingRight();
        int columnsNumber = determineColumns(childWidth);
        if (columnsNumber > 0 && columnsNumber != itemsPerRow) {
            itemsPerRow = columnsNumber;
            removeAllViews();
            processViews();
        }
    }

    protected int  determineColumns(int availableSpace) {
        int columnsNumber = itemsPerRow;
        if (0 < columnWidth) {
            columnsNumber = availableSpace / columnWidth;
        } 
        return columnsNumber;
    }

}

这是我的自定义属性资源文件:

Here is my resource file for the custom attributes:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <attr name="column_width" format="dimension|integer">
        <enum name="single_column" value="-1" />
    </attr>
    <declare-styleable name="GridLikeLayout">
        <attr name="column_width" />
    </declare-styleable>

</resources>

这是一个示例用法:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layoutContainer"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <ScrollView
        android:id="@+id/itemsScroller"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <LinearLayout
            android:id="@+id/itemsLayout"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <your_package.view.GridLikeLayout
                xmlns:my="YOUR APPLICATION PACKAGE"
                android:id="@+id/MyGrid"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                my:column_width="260dp"
                android:focusable="true"
                android:gravity="center_horizontal"
                android:padding="5dp" >
            </your_package.GridLikeLayout>

            <View
                android:id="@+id/viewSeparator"
                android:layout_width="fill_parent"
                android:layout_height="2dp" />

            <your_package.GridLikeLayout
                xmlns:my="YOUR APPLICATION PACKAGE"
                android:id="@+id/list"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                my:column_width="single_column" >
            </your_package.GridLikeLayout>

        </LinearLayout>
    </ScrollView>

</FrameLayout>

如果您在运行示例时遇到任何问题,请告诉我 - 我目前无法尝试.所以如果你有问题,我会稍后检查.不要忘记更改包名称 - your_package"应该是您存储 GridLikeLayout 的包,而YOUR APPLICATION PACKAGE"是您的应用程序包 - 在应用程序清单中指定的包.:)

Please tell me if you have any troubles running the example - I'm not able to try it at the moment. So if you have issues, I'll check it up later. Don't forget to change the package names - "your_package" should be the the package where you store the GridLikeLayout and "YOUR APPLICATION PACKAGE" is your app's package - the one specified in the application manifest. :)

这篇关于如何在android java中将多个gridviews添加到scrollview?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆