简体   繁体   中英

How to re-position the grid layout elements in fragments on orientation change?

I am having a bottom tabbed activity with three fragments Home, Dashboard and Notifications. In the first fragment, I am having 4 layouts with a button in each layout. These 4 layouts are aligned ina grid view having positions as column:rows (1:1 1:2 2:1 2:2) while in portrait orientation.

But how to auto-arrange these layouts when in landscape mode ie either as (1:1 1:2 1:3 1:4) based on the horizontal area available during landscape?

在此处输入图像描述

Xml File

    <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:grid2="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center">

    <ScrollView
        android:id="@+id/scroll"
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <androidx.gridlayout.widget.GridLayout
        android:id="@+id/container2"
        android:layout_width="match_parent"
        android:background="#00555555"
        android:layout_height="wrap_content"
        android:paddingTop="?attr/actionBarSize"
        grid2:alignmentMode="alignBounds"
        grid2:columnCount="2"
        android:numColumns="auto_fit"
        android:stretchMode="columnWidth"
        grid2:rowOrderPreserved="false">

        <LinearLayout
            android:id="@+id/layout1"
            android:layout_width="180dp"
            android:layout_height="170dp"
            android:background="@drawable/circle_shape"
            android:gravity="center"
            android:orientation="vertical"
            android:text="TextView"
            grid2:layout_column="0"
            grid2:layout_gravity="center"
            grid2:layout_row="0">

                <Button
                    android:id="@+id/but1"
                    android:layout_width="55dp"
                    android:layout_height="56dp"
                    android:layout_gravity="center"
                    android:background="@drawable/button1"
                    android:layout_marginTop="20dp"
                    grid2:layout_gravity="left" />

                <TextView
                    android:id="@+id/tv1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginTop="8dp"
                    android:text="@string/control"
                    android:textSize="22sp"
                    android:textStyle="italic" />

                <TextView
                    android:id="@+id/tv2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:textColor="#25F325"
                    android:text="@string/no_status"
                    android:textSize="14sp" />
            </LinearLayout>

        <LinearLayout
            android:id="@+id/layout2"
            android:layout_width="180dp"
            android:layout_height="170dp"
            android:layout_marginEnd="20dp"
            android:background="@drawable/circle_shape"
            android:gravity="center"
            android:orientation="vertical"
            grid2:layout_column="1"
            grid2:layout_gravity="center_horizontal"
            grid2:layout_row="0">

                <Button
                    android:id="@+id/but2"
                    android:layout_width="55dp"
                    android:layout_height="56dp"
                    android:layout_marginTop="10dp"
                    android:layout_gravity="center"
                    android:background="@drawable/button2" />

                <TextView
                    android:id="@+id/tv4"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginTop="10dp"
                    android:textStyle="italic"
                    android:textSize="21sp" />

                <TextView
                    android:id="@+id/tv5"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginBottom="10dp"
                    android:text="@string/no_data"
                    android:textColor="#25F325"
                    android:textSize="14sp" />
            </LinearLayout>

        <LinearLayout
            android:id="@+id/layout3"
            android:layout_width="180dp"
            android:layout_height="170dp"
            android:layout_marginStart="20dp"
            android:layout_marginEnd="10dp"
            android:background="@drawable/circle_shape"
            android:gravity="center"
            android:orientation="vertical"
            grid2:layout_column="0"
            grid2:layout_gravity="center"
            grid2:layout_row="1">

                <Button
                    android:id="@+id/but3"
                    android:layout_marginTop="0dp"
                    android:layout_width="60dp"
                    android:layout_height="60dp"
                    android:layout_gravity="center"
                    android:background="@drawable/img1" />

                <TextView
                    android:id="@+id/tv6"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginTop="10dp"
                    android:text="Fire"
                    android:textSize="21sp"
                    android:textStyle="italic" />

                <TextView
                    android:id="@+id/tv7"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:text="@string/no_data"
                    android:textColor="#25F325"
                    android:textSize="14sp" />
            </LinearLayout>

        <LinearLayout
            android:id="@+id/layout4"
            android:layout_width="180dp"
            android:layout_height="170dp"
            android:layout_marginTop="10dp"
            android:layout_marginEnd="20dp"
            android:background="@drawable/circle_shape"
            android:gravity="center"
            android:orientation="vertical"
            android:text="TextView"
            grid2:layout_column="1"
            grid2:layout_gravity="center"
            grid2:layout_row="1">

            <Button
                android:id="@+id/but4"
                android:layout_width="60dp"
                android:layout_height="60dp"
                android:layout_gravity="center"
                android:background="@drawable/gas1" />

            <TextView
                android:id="@+id/tv8"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginTop="10dp"
                android:text="Gas"
                android:textSize="21sp"
                android:textStyle="italic" />

            <TextView
                android:id="@+id/tv9"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:textColor="#25F325"
                android:text="@string/no_data
                android:textSize="14sp" />
        </LinearLayout>

</androidx.gridlayout.widget.GridLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

Home Fragment Class

    package com.example.qnorb.ui.home;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

import com.example.qnorb.R;

public class HomeFragment extends Fragment implements View.OnClickListener{

    private HomeViewModel homeViewModel;

    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        homeViewModel = ViewModelProviders.of(this).get(HomeViewModel.class);
        View root = inflater.inflate(R.layout.fragment_home, container, false);
       // textView = root.findViewById(R.id.lights);
        homeViewModel.getText().observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
            }
        });
        return root;
    }

    @Override
    public void onClick(View view) {

    }
}

Home View Model Class

 package com.example.qnorb.ui.home;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

public class HomeViewModel extends ViewModel {

    private MutableLiveData<String> mText;

    public HomeViewModel() {
        mText = new MutableLiveData<>();
    }

    public LiveData<String> getText() {
        return mText;
    }
}

Target API 13+:

Set the android:configChanges flag in your Activity in manifest.xml

<activity
    android:name="com.test.activity.MainActivity"
    android:configChanges="orientation|screenSize|keyboardHidden"/>

I would suggest use RecyclerView pattern with different spanCount after rotation configuration changes.

Also you can calculate span count by screen width or whatever.

So basically in onCreate() , set new GridLayoutManager(context, GRID_SPAN_COUNT_BY_ROTATION) in to RecyclerView

it should look like this in your fragment:

    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        homeViewModel = ViewModelProviders.of(this).get(HomeViewModel.class);
        View root = inflater.inflate(R.layout.fragment_home, container, false);
        RecyclerView recyclerView = root.findViewById(R.id.your_recyclerview);


        // set span count by orientation
        int orientation = getResources().getConfiguration().orientation;
        int spanCount;
        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
            // code for portrait mode
            spanCount = 4;
        } else {
            // code for landscape mode
            spanCount = 9;
        }

        // set GridLayoutManager with custom span count
        recyclerView.setLayoutManager(new GridLayoutManager(context, spanCount));

        homeViewModel.getText().observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
            }
        });
        return root;
    }

if it is not working then do not forget to change manifest config rules like mentioned in another answer.

You need to have two different layouts for portrait and landscape orientation.

it should be named same name, but in different layout directories:

layout dir where your current layout is for Portrait orientation.

Now create layout-land directory, copy same layout and refactor it with same view id's just different positions.

It should look like this:

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM