ScrollView 和 GridView 冲突

ScrollView and GridView clashes

我使用了滚动视图,因为我的视图很长,我需要让用户向下滚动以查看 TextViews 和 ImageViews 等项目。但是在底部我需要有一个 GridView 来显示无限的图像列表。

I need to be able to scroll to view the textviews

I also need to be able to reach the GridView and scroll away

但是,我意识到不能在 Scrollview 中包含 GridView,因为它们都涉及滚动,而且一些奇怪的错误使我无法滚动 GridView。我的情况有什么替代方案?

代码示例:

<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

<TextView
            android:id="@+id/text1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="5dp"
            android:layout_marginTop="30dp"
            android:text="Hello there"
            android:textColor="#CC000000"
            android:textSize="25sp" />
<TextView
            android:id="@+id/text2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="5dp"
            android:layout_marginTop="30dp"
            android:text="Partner Name: "
            android:textColor="#CC000000"
            android:textSize="25sp" />

<!-- Lot more TextViews -->

<!-- And then comes the GridView -->

 <GridView
            android:id="@+id/picturefeed"
            android:numColumns="3"
            android:layout_marginTop="20dp"
            android:layout_below="@+id/partner_details"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

        </GridView>
</ScrollView>

您需要一个具有 GridLayoutManager 的异构 RecyclerView。

您应该查看 Creating Lists and Cards 指南。

这是一个示例:

@Override
protected void onCreate (Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.your_main_layout);

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.your_recycler_view);

    final MyAdapter adapter = new MyAdapter();

    GridLayoutManager layoutManager = new GridLayoutManager(this, 3); // a row can be 3 spans wide
    layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            switch(adapter.getItemViewType(position)){
                case MyAdapter.TYPE_TEXT:
                    return 3; // it's going to take up a row
                case MyAdapter.TYPE_IMAGE:
                    return 1; // it's going to take up 1/3 of a row
                default:
                    return -1;
            }
        }
    });

    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setAdapter(adapter);
}

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    public static final int TYPE_TEXT = 1;
    public static final int TYPE_IMAGE = 2;

    @Override
    public int getItemViewType (int position) {
        if (position < 2) { // the first two items of the RecyclerView will be the TextView ones
                            // you can (should?) use a more sophisticated method if you want to
            return TYPE_TEXT;
        }

        // the rest of the items are images
        return TYPE_IMAGE;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerView.ViewHolder viewHolder;
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());

        switch (viewType) {
            case TYPE_TEXT:
                View v1 = inflater.inflate(R.layout.layout_vh_text, parent, false);
                viewHolder = new TextViewHolder(v1);
                break;
            case TYPE_IMAGE:
                View v2 = inflater.inflate(R.layout.layout_vh_image, parent, false);
                viewHolder = new ImageViewHolder(v2);
                break;
            default:
                throw new IllegalArgumentException("Unsupported view type: " + viewType);
        }

        return viewHolder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
        switch (viewHolder.getItemViewType()) {
            case TYPE_TEXT:
                TextViewHolder vh1 = (TextViewHolder) viewHolder;
                // do something with vh1
                break;
            case TYPE_IMAGE:
                ImageViewHolder vh2 = (ImageViewHolder) viewHolder;
                // do something with vh2
                break;
            default:
                throw new IllegalArgumentException("Unsupported view type: " + viewType);
        }
    }

    public class TextViewHolder extends RecyclerView.ViewHolder {
        // ...
    }

    public class ImageViewHolder extends RecyclerView.ViewHolder {
        // ...
    }

    // rest of the adapter's code, not explained here as it's not part of the question
}