List view grid or 2 list views better?

I tried to get a combo box view in my activity, but I got an error.

Is there any other way to get the result below?

In my main activity, I want one list view to display a large image and the second to display them as 2 images per line, should I use a grid view or is the second list view enough?

enter image description here

this is my code

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:fillViewport="true" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
          android:text="sssss"
            android:textSize="16sp"
            android:padding="10dp"
            android:background="#ffe474" />

        <ListView
            android:id="@+id/list3"
            android:layout_width="wrap_content"
            android:layout_height="1500dp"
            android:background="#eeeeee" >
        </ListView>

         <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:text="Recommanded"
            android:textSize="18sp"
            android:padding="10dp"
            android:background="#ffe474" />


        <ListView
            android:id="@+id/list1"
            android:layout_width="wrap_content"
            android:layout_height="1500dp"
            android:background="#eeeeee" >
        </ListView>

    </LinearLayout>


</ScrollView>

      

+3


source to share


4 answers


This is a bit tricky thing. Whenever we get such a requirement, we have to do a workaround like keeping the LinearLayout with orientation as vertical and keep the LinearLayout inside the ScrollView . I created a sample for your problem. Hope this helps you.

custom_grid_item.xml:  

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/layout_horizontal"
              android:orientation="horizontal"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:background="@android:color/black">

    <LinearLayout
            android:id="@+id/gridItemLeft"
            android:orientation="horizontal"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:layout_margin="4dp"
            android:gravity="left"
            android:visibility="invisible">

        <TextView
                android:id="@+id/itemNameLeft"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textAppearance="@android:style/TextAppearance.Medium"
                android:text="@string/app_name"
                android:textColor="@android:color/black"
                android:padding="4dp"
                android:background="@android:color/white"/>

    </LinearLayout>

    <LinearLayout
            android:id="@+id/gridItemRight"
            android:orientation="horizontal"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:layout_margin="4dp"
            android:gravity="right"
            android:visibility="invisible">

        <TextView
                android:id="@+id/itemNameRight"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="4dp"
                android:textAppearance="@android:style/TextAppearance.Medium"
                android:text="@string/app_name"
                android:textColor="@android:color/black"
                android:background="@android:color/white"/>

    </LinearLayout>
</LinearLayout>

      

custom_list_item.xml:

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

<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="4dp"
        android:background="@android:color/black">

    <TextView
            android:id="@+id/itemName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAppearance="@android:style/TextAppearance.Medium"
            android:background="@android:color/white"
            android:padding="8dp"
            android:text="@string/app_name"
            android:textColor="@android:color/black"/>

</LinearLayout>

      

main.xml:



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/black">

    <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        <LinearLayout
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

            <LinearLayout
                    android:orientation="vertical"
                    android:id="@+id/custom_list"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@android:color/white"/>

            <LinearLayout
                    android:orientation="vertical"
                    android:id="@+id/custom_grid"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@android:color/white"/>

        </LinearLayout>

    </ScrollView>

</LinearLayout>

      

MyActivity.java:

public class MyActivity extends Activity {

    private List<String> mItems;
    private LinearLayout mListLayout, mGridLayout;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mItems = new ArrayList<String>(Arrays.asList("Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Item 10"));

        mListLayout = (LinearLayout) findViewById(R.id.custom_list);
        mGridLayout = (LinearLayout) findViewById(R.id.custom_grid);

        loadListView();
        loadGridView();

    }

    private void loadGridView() {
        if (mItems.size() % 2 == 0) {
            loadEvenGridView(true);
        } else {
            loadEvenGridView(false);

            LayoutInflater inflater = getLayoutInflater();
            LinearLayout gridItem = (LinearLayout) inflater.inflate(R.layout.custom_grid_item, null);
            LinearLayout leftItem = (LinearLayout) gridItem.findViewById(R.id.gridItemLeft);
            LinearLayout rightItem = (LinearLayout) gridItem.findViewById(R.id.gridItemRight);
            leftItem.setVisibility(View.VISIBLE);
            rightItem.setVisibility(View.INVISIBLE);
            TextView txtItemName = (TextView) gridItem.findViewById(R.id.itemNameLeft);
            txtItemName.setText(mItems.get(mItems.size() - 1));
            leftItem.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(getApplicationContext(), mItems.get(mItems.size() - 1), Toast.LENGTH_SHORT).show();
                }
            });
            mGridLayout.addView(gridItem);
        }
    }

    private void loadEvenGridView(boolean isEvenSize) {
        int len = mItems.size();
        if (!isEvenSize) {
            len = len - 1;
        }
        if (len > 1) {
            for (int index = 1; index < len; index += 2) {
                LayoutInflater inflater = getLayoutInflater();
                LinearLayout gridItem = (LinearLayout) inflater.inflate(R.layout.custom_grid_item, null);
                LinearLayout leftItem = (LinearLayout) gridItem.findViewById(R.id.gridItemLeft);
                LinearLayout rightItem = (LinearLayout) gridItem.findViewById(R.id.gridItemRight);
                TextView txtItemName;
                for (int sIndex = 0; sIndex < 2; sIndex++) {
                    switch (sIndex) {
                        case 0:
                            leftItem.setVisibility(View.VISIBLE);
                            txtItemName = (TextView) gridItem.findViewById(R.id.itemNameLeft);
                            txtItemName.setText(mItems.get(index - 1));
                            final int finalIndex = index;
                            leftItem.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {
                                    Toast.makeText(getApplicationContext(), mItems.get(finalIndex - 1), Toast.LENGTH_SHORT).show();
                                }
                            });
                            continue;
                        case 1:
                            rightItem.setVisibility(View.VISIBLE);
                            txtItemName = (TextView) gridItem.findViewById(R.id.itemNameRight);
                            txtItemName.setText(mItems.get(index));
                            final int finalIndex1 = index;
                            rightItem.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {
                                    Toast.makeText(getApplicationContext(), mItems.get(finalIndex1), Toast.LENGTH_SHORT).show();
                                }
                            });
                            continue;
                    }
                }
                mGridLayout.addView(gridItem);
            }
        }
    }

    private void loadListView() {
        for (int index = 0; index < mItems.size(); index++) {
            LayoutInflater inflater = getLayoutInflater();
            View listItem = inflater.inflate(R.layout.custom_list_item, null);
            TextView txtItemName = (TextView) listItem.findViewById(R.id.itemName);
            txtItemName.setText(mItems.get(index));
            mListLayout.addView(listItem);
            final int finalIndex = index;
            listItem.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(getApplicationContext(), mItems.get(finalIndex), Toast.LENGTH_SHORT).show();
                }
            });
        }
    }
}

      

Screenshot:

Screenshot of your problem

+1


source


A more suitable and simpler solution would be to use a RecyclerView with a GridLayoutManager. The GridLayoutManager takes a SpanSizeLookup object that lets you specify how many spacing each of the elements will take.

The complete solution to this problem includes the following parts:

Activity with RecyclerView, GridLayoutManager and custom SpanSizeLookup

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        // specify that grid will consist of 2 columns
        GridLayoutManager gridLayoutManager = new GridLayoutManager(getApplicationContext(), 2);
        // provide our CustomSpanSizeLookup which determines how many spans each item in grid will occupy
        gridLayoutManager.setSpanSizeLookup(new CustomSpanSizeLookup());
        // provide our GridLayoutManager to the view
        recyclerView.setLayoutManager(gridLayoutManager);
        // this is fake list of images
        List<Integer> imageResList = getMockedImageList();
        // finally, provide adapter to the recycler view
        Adapter adapter = new Adapter(imageResList);
        recyclerView.setAdapter(adapter);
    }


    private List<Integer> getMockedImageList() {
        // fake images list, you'd need to upload your own image resources
        List<Integer> imageResList = new ArrayList<Integer>();

        imageResList.add(R.drawable.img1);
        imageResList.add(R.drawable.img2);
        imageResList.add(R.drawable.img3);
        imageResList.add(R.drawable.img4);
        imageResList.add(R.drawable.img5);
        imageResList.add(R.drawable.img6);

        return imageResList;
    }


    private static class CustomSpanSizeLookup extends GridLayoutManager.SpanSizeLookup {
        @Override
        public int getSpanSize(int i) {
            if(i == 0 || i == 1) {
                // grid items on positions 0 and 1 will occupy 2 spans of the grid
                return 2;
            } else {
                // the rest of the items will behave normally and occupy only 1 span
                return 1;
            }
        }
    }
}

      

RecyclerView adapter

public class Adapter extends RecyclerView.Adapter {
    // I assume that you will pass images as list of resources, but this can be easily switched to a list of URLS
    private List<Integer> imageResList = new ArrayList<Integer>();

    public Adapter(List<Integer> imageUrlList) {
        this.imageResList = imageUrlList;
    }


    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recycle_view_item, viewGroup, false);

        return new ItemViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
        ItemViewHolder itemViewHolder = (ItemViewHolder) viewHolder;
        itemViewHolder.item.setImageResource(imageResList.get(i));
    }

    @Override
    public int getItemCount() {
        return imageResList.size();
    }


    private static class ItemViewHolder extends RecyclerView.ViewHolder {
        private ImageView item;

        public ItemViewHolder(View itemView) {
            super(itemView);

            this.item = (ImageView) itemView.findViewById(R.id.item_image);
        }
    }
}

      

activity_main.xml layout

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

      

recycler_view_item.xml layout



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="150dp"
    android:padding="10dp">

    <ImageView
        android:id="@+id/item_image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"/>

</LinearLayout>

      

And the last snippet would be to add a dependency in the build.gradle file for the RecyclerView:

dependencies {
    compile 'com.android.support:recyclerview-v7:21.0.+'
}

      

And here's the result:

enter image description here

The advantages of this solution are as follows:

  • it is scalable, lightweight and highly customizable
  • it is efficient when it recycles views when scrolling up and down
  • no need to fiddle with touch events, which can easily become very complex to handle after adding additional touch functionality.

I hope this is helpful.

+1


source


There is a fairly simple way to implement this: - AsymmetricGridView

Hope this helps you!

+1


source


You can't just scroll View

inside another scrollable View

and expect them to work out of the box, especially if they both scroll in the same direction. The best way to make this possible is to extend these Views and intercept the sensory events that are sent to them. Here you can define the user-generated scroll direction and route the touch event accordingly.

Read the following: Intercept Touch Events in a ViewGroup

0


source







All Articles