水平滚动自定义网格

时间:2014-02-17 05:57:01

标签: android android-layout

我需要水平滚动自定义网格列表。我已经分别实现了一个网格和一个水平滚动列表。但是,当我将两个代码组合在一起时,它不起作用。有人可以建议任何方式来做到这一点?感谢您的帮助。

先谢谢。

这是我的xml:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    >

    <HorizontalScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        android:scrollbars="none">
        <LinearLayout
            android:id="@+id/mygallery"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            />
    </HorizontalScrollView>

</LinearLayout>

这是我的代码:

 LinearLayout myGallery = (LinearLayout)findViewById(R.id.mygallery);

        for(int i=0; i<4 ; i++)
        {
 LayoutInflater inflater =  getLayoutInflater();    
        LinearLayout layout=(LinearLayout) inflater.inflate(R.layout.scroll_view_item, null);
            GridView gridView = (GridView)layout.findViewById(R.id.gridview);
            gridView.setAdapter(new MyAdapter(this));
         myGallery.addView(layout);
        }

        myGallery.setHorizontalScrollBarEnabled(false);
        myGallery.setVerticalScrollBarEnabled(false);

1 个答案:

答案 0 :(得分:0)

您无法在Android中嵌套可滚动视图 - 即ListView,GridView,ScrollView。

您可以查看以下代码:

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更重。

在我的情况下,我最终扩展了LinearLayout并使用它来将其子项与列对齐。这不是很难 - 如果你愿意,我可以给你一些例子。 :)

我从Grid of images inside ScrollView回答中获得了GridView示例。

以下是基于LinearLayout的GridView示例:

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

}

以下是自定义属性的资源文件:

<?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”是应用程序的软件包 - 应用程序清单中指定的软件包。 :)

希望它可以帮助您获得解决方案......

相关问题