Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ListView or GridView dynamically based on Layout Used By Device

I'm making an activity in my app to display a bunch of data, specifically places. There will be the place name, the distance away from the user, and an image to go with it. All this part I have got sorted.

I want to display this information differently on different devices. On a smaller device e.g. phone I want them to be displayed in a 1 column list, image on the left, and the name and distance on the right. I already have this set up using a ListView.

However, on a larger tablet I'd like to display it in a grid, with the image being the whole cell (square) and the text on top of the image.

What would be the best approach to this. Would it be 2 layouts, one ListView and one GridView, and how will the Activity.java file detect which is present and format the data accordingly? Or could I just use a GridView and dynamically set the columns depending on screen size?

like image 437
TMH Avatar asked Sep 25 '13 09:09

TMH


2 Answers

ListView & GridView are both descendants of AbsListView. So, in your code, refer to an instance of AbsListView. Then, as someone else suggested, use the specific layout folders to define your layouts. You will also define the specific instance of AbsListView within these layouts (ListView or GridView).

If you define the layouts correctly with all the same element names, your code won't need to change.

EDIT: I'm not sure why you would ever write code to do something the SDK/OS will do for you. So, for others who stumble upon this, I wanted to give a full example of how to do this without having to put a hack in your code:

The full, very basic project can be found on my gitHub here: https://github.com/sberg413/abslistview-example

The MainActivity.java :

package com.example.abslistviewexample;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;    

public class MainActivity extends Activity {

        AbsListView absListView;

        static String[] listItems = { "First Item", "Second Item", "Third Item",
                "Fourth Item", "Fifth Item", "Sixth Item", "Seventh Item",
                "Eight Item", "Ninth Item", "Tenth Item" };

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

            absListView = (AbsListView) findViewById(R.id.listView1);

            absListView.setAdapter( new MyArrayAdapter(this, R.layout.row, listItems));
        }


        private class MyArrayAdapter extends ArrayAdapter<String>{

            public MyArrayAdapter(Context context, int resource,
                    String[] values) {
                super(context, resource, values);   
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                LayoutInflater inflater = (LayoutInflater) getContext()
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                View view = inflater.inflate(R.layout.row, parent, false);
                TextView textView = (TextView) view.findViewById(R.id.textView1);
                ImageView imageView = (ImageView) view.findViewById(R.id.imageView1);

                textView.setText( getItem(position));

                return view;
            }
        }
}

The layout/activity_main.xml :

<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"
    tools:context=".MainActivity" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" >

    </ListView>
</RelativeLayout>

The layout/row.xml :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/imageView1"
        android:layout_marginLeft="50dp"
        android:layout_toRightOf="@+id/imageView1"
        android:text="TextView" />
</RelativeLayout>

The layout-xlarge/activity_main.xml :

<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"
    tools:context=".MainActivity" >

    <GridView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:numColumns="3" >

    </GridView>
</RelativeLayout>

The layout-xlarge/row.xml :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="20dp"
        android:text="TextView" />
</RelativeLayout>

This is obviously a very trivial example, but you'll get the idea. Notice how the MainActivity uses an AbsListView. Within the layout xmls you specify which child class is used.

I hope this helps someone.

like image 185
SBerg413 Avatar answered Oct 15 '22 11:10

SBerg413


What you are doing is the perfect way. Do GridView for 7 inch and 10 inch tab and for rest listview. Use two different layout files and below code to detect the device if 7 inch tablet or 10 inch tablet or other.

public static Double getDiagonalInch(Activity activity)

{

    DisplayMetrics metrics = new DisplayMetrics();

    WindowManager wm = (WindowManager) activity.getSystemService(
            Context.WINDOW_SERVICE);
    wm.getDefaultDisplay().getMetrics(metrics);
      final int measuredwidth = metrics.widthPixels;
      final int measuredheight = metrics.heightPixels;

      final double diagonal = Math.sqrt((measuredwidth * measuredwidth)
        + (measuredheight * measuredheight));


      diaInch = diagonal / metrics.densityDpi;

    return diaInch;

}
if(diaInch<9 && diaInch>=6.5)
        {
            // small tab (7 inch tab)
        }
        else if(diaInch>9)
        {
            // big tab (10 inch tab)
        }
        else
        {
            s2,s3 s4 etc devices
        }
like image 44
Abhijit Kurane Avatar answered Oct 15 '22 12:10

Abhijit Kurane