1

What's the most efficient way to adapt a layout use the same click events for my activity lst items? I have only seen this and this but they don't fully resolve the issue.

Current phone code XML (activity_main.xml)

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

    <ListView
        android:id="@+id/my_listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

Java

public class MainActivity extends Activity implements MyRecyclerViewAdapterGL.ItemClickListener, MyRecyclerViewAdapterLL.ItemClickListener {

    MyRecyclerViewAdapterGL adapterGL;
    MyRecyclerViewAdapterLL adapterLL;

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

        // data to populate the RecyclerView with
        String[] dataArray = {"Item A", "Item B", "Item C", "Item D" ,"Item E" ,"Item F"};


        // set up the RecyclerView (phones)
        RecyclerView recyclerViewLL = findViewById(R.id.recyclerView_list);
        recyclerViewLL.setLayoutManager(new LinearLayoutManager(this));
        adapterLL = new MyRecyclerViewAdapterLL(this, dataArray);
        adapterLL.setClickListener(this);
        recyclerViewLL.addItemDecoration(new DividerItemDecoration(this, LinearLayout.VERTICAL));
        recyclerView.setAdapter(adapterLL);


        // set up the RecyclerView (sw600dp)
        RecyclerView recyclerViewGL = findViewById(R.id.recyclerView_list);
        int numberOfColumns = 2;
        recyclerViewGL.setLayoutManager(new GridLayoutManager(this, numberOfColumns));
        adapterGL = new MyRecyclerViewAdapterGL(this, dataArray);
        adapterGL.setClickListener(this);
        recyclerViewGL.setAdapter(adapterGL);
    }

    @Override
    public void onItemClick(View view, int position) {
    }
}

Current phone result

enter image description here

Previously used tablet code (sw600dp/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<TableLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/listview_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:stretchColumns="*"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin">
    <TableRow
        android:id="@+id/MainActivity_tableRow0"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp" >


        <Button
            android:id="@+id/MainActivity_btn0"
            android:layout_column="0"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginEnd="10dp"
            android:gravity="start|center_vertical"
            android:padding="30dp"
            android:text="Item A"
            android:textAllCaps="false"
            android:textColor="?android:attr/textColorPrimary"
            style="@style/TextAppearance.AppCompat.Large"
            />

        <Button
            android:id="@+id/MainActivity_btn1"
            android:layout_column="1"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginStart="10dp"
            android:gravity="start|center_vertical"
            android:padding="30dp"
            android:text="Item B"
            android:textAllCaps="false"
            android:textColor="?android:attr/textColorPrimary"
            style="@style/TextAppearance.AppCompat.Large"
            />
    </TableRow>

    <TableRow
        android:id="@+id/MainActivity_tableRow1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp" >

        <Button
            android:id="@+id/MainActivity_btn2"
            android:layout_column="0"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginEnd="10dp"
            android:gravity="start|center_vertical"
            android:padding="30dp"
            android:text="Item C"
            android:textAllCaps="false"
            android:textColor="?android:attr/textColorPrimary"
            style="@style/TextAppearance.AppCompat.Large"
            />

        <Button
            android:id="@+id/MainActivity_btn3"
            android:layout_column="1"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginStart="10dp"
            android:gravity="start|center_vertical"
            android:padding="30dp"
            android:text="Item D"
            android:textAllCaps="false"
            android:textColor="?android:attr/textColorPrimary"
            style="@style/TextAppearance.AppCompat.Large"
            />
    </TableRow>

    <TableRow
        android:id="@+id/MainActivity_tableRow2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/MainActivity_btn4"
            android:layout_column="0"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginEnd="10dp"
            android:gravity="start|center_vertical"
            android:padding="30dp"
            android:text="Item E"
            android:textAllCaps="false"
            android:textColor="?android:attr/textColorPrimary"
            style="@style/TextAppearance.AppCompat.Large"
            />

        <Button
            android:id="@+id/MainActivity_btn5"
            android:layout_column="1"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginStart="10dp"
            android:gravity="start|center_vertical"
            android:padding="30dp"
            android:text="Item G"
            android:textAllCaps="false"
            android:textColor="?android:attr/textColorPrimary"
            style="@style/TextAppearance.AppCompat.Large"
            />
    </TableRow>
</TableLayout>

Expected tablet result

enter image description here

Current tablet result

enter image description here

values/bools.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="my_boolean_value">true</bool>
</resources>

values-sw600dp/bools.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="my_boolean_value">true</bool>
</resources>
wbk727
  • 8,017
  • 12
  • 61
  • 125
  • What's the question? – George Arokiam Aug 27 '18 at 17:19
  • @GeorgeArokiam change the layout based on screen width and use the same click events – wbk727 Aug 27 '18 at 17:20
  • If you use a RecyclerView you don't even need two layout files but you can set two different LayoutManagers (LinearLayout and GridLayout) depending on some (boolean) resource with different values in res/values and res/values-sw600dp – Bö macht Blau Aug 27 '18 at 17:21
  • @0X0nosugar are there any examples of this in action available? – wbk727 Aug 27 '18 at 17:29
  • I found these: [https://developer.android.com/guide/topics/resources/more-resources#Bool](https://developer.android.com/guide/topics/resources/more-resources#Bool), [https://stackoverflow.com/a/40587169/5015207](https://stackoverflow.com/a/40587169/5015207) – Bö macht Blau Aug 27 '18 at 17:35
  • @0X0nosugar okay but I'm still struggling to find the Java code to detect if the device's screen width is `sw600dp` or not – wbk727 Aug 28 '18 at 15:18
  • You can define one boolean resource (...)and let it have one value in the default file (res/values/bools.xml) and another one in the "special" file (res/**values-sw600dp**/bools.xml). At runtime you evaluate the value you get by calling getResources().getBoolean(R.bool.my_boolean_value). and decide which LayoutManager to use – Bö macht Blau Aug 28 '18 at 17:03
  • You don't have to determine the screen size. You'll get one value or the other *depending on the screen size* – Bö macht Blau Aug 28 '18 at 17:05
  • What replaces the 3 dots in `...`? Please check out my updated `MainActivity` Java class – wbk727 Aug 28 '18 at 19:59

1 Answers1

1

You can use a RecyclerView with two different LayoutManagers (LinearLayout and GridLayout). In order to determine the size of the device, you will need to evaluate a boolean resource for which you provide different values depending on the screen size.

In res/values/bools.xml

<bool name="is_screen_small">true</bool>

In res/values-sw600dp/bools.xml

<bool name="is_screen_small">false</bool>

In onCreate(), you use a boolean variable to retrieve the value like this:

boolean isScreenSmall = getResources().getBoolean(R.bool.is_screen_small);

Since the correct value will be handed to you by the runtime, you can use it to set up the RecyclerView with the correct LayoutManager:

RecyclerView recyclerView = findViewById(R.id.recyclerView_list);
LayoutManager layoutManager;
if(isScreenSmall){
    layoutManager = new LinearLayoutManager(this);
    // maybe use special ItemDecoration for small devices
}
else{
    int numberOfColumns = 2;
    layoutManager = new GridLayoutManager(this, numberOfColumns);
    // maybe use special ItemDecoration for large devices
}
recyclerView.setLayoutManager(layoutManager);
MyAdapter adapter = new MyAdapter(this, dataArray);
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);

Note that I'm using the same RecyclerView and RecyclerView.Adapter for both screen sizes. This will work if I can guarantee that the list items don't get too wide, which is the case for many lists.

Since a "normal" screen may be only 320dp wide and one should leave room for left and right margins of 16dp ("should" because of the material design guidelines), the list items should not be wider than 288dp anyway. But on a device with screen width 600dp, one has to use wider margins (24dp) so one should aim at having list items with a max width of 270dp, then they will also fit into a GridLayout with two columns

You can also avoid having lots of layout files and instead do some fine tuning on your layouts by providing different dimension values (for margins, padding, width, height, etc.) for different screen sizes.

wbk727
  • 8,017
  • 12
  • 61
  • 125
Bö macht Blau
  • 12,820
  • 5
  • 40
  • 61