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

五迷三道 提交于 2021-01-29 07:11:00

问题


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 i.e. 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;
    }
}

回答1:


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"/>



回答2:


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:




回答3:


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 toRecyclerView

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.



来源:https://stackoverflow.com/questions/61201429/how-to-re-position-the-grid-layout-elements-in-fragments-on-orientation-change

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!