我需要水平滚动自定义网格列表。我已经分别实现了一个网格和一个水平滚动列表。但是,当我将两个代码组合在一起时,它不起作用。有人可以建议任何方式来做到这一点?感谢您的帮助。
先谢谢。
这是我的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);
答案 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”是应用程序的软件包 - 应用程序清单中指定的软件包。 :)
希望它可以帮助您获得解决方案......