Textview in android fragment duplicated in landsca

2019-09-17 04:48发布

I am trying to make an app with two fragments, one containing a list of groups (called OverviewFragment) and one fragment containing the details of selected group (called DetailsFragment). I want only one fragment to be visible at a time in portrait mode and both to be visible simultaneously in landscape mode.

I have two problems. First of all the transition between portrait and landscape is very unstable and leads to a variety of crashes, i.e: a blank screen, "No view found", "Error inflating class fragment" and "overlapping rendering".

My other more concrete problem is that when in landscape mode, the textview containing the group name is duplicated and added at the top of the layout. To me this is very strange since the other textview (containing the group info) does NOT get duplicated. Very puzzling!

Running the app in portrait mode alone works fine and I experience no crashes or duplicated textviews.

MainActivity.java

package com.example.o2k.lab2naviedition;

import android.net.Uri;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements OverviewFragment.OnOverviewInteractionListener, DetailsFragment.OnDetailsInteractionListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState != null) { // if we are being restored we dont need to do stuff
            System.out.println("saved");
            return;
        }
        System.out.println("tag is: "+findViewById(R.id.activity_main).getTag());

        if (findViewById(R.id.activity_main).getTag().equals("portrait")) {
            OverviewFragment overFrag = new OverviewFragment();
            System.out.println("PORTRAIT IF ---------------------");
            // Add the fragment to the 'fragment_container' FrameLayout
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.fragment_container, overFrag).commit();

        } else if (findViewById(R.id.activity_main).getTag().equals("landscape")) {
            System.out.println("LANDSCAPE IF ---------------------");
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.overview_fragment, new OverviewFragment());
            transaction.replace(R.id.details_fragment, new DetailsFragment());
            transaction.commit();
        }
    }

    @Override
    public void onOverviewInteraction(int position) {
        DetailsFragment detailsFrag = (DetailsFragment)
                getSupportFragmentManager().findFragmentById(R.id.details_fragment);

        Group group = OverviewFragment.getGroups()[position];
        DetailsFragment newFragment = new DetailsFragment();
        Bundle args = new Bundle();
        args.putString("groupName", group.getName());
        args.putString("groupInfo", group.getInfo());
        newFragment.setArguments(args);
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

        if (detailsFrag != null) {
            transaction.replace(R.id.details_fragment, newFragment);
        } else {
            transaction.replace(R.id.fragment_container, newFragment);
            transaction.addToBackStack(null);
        }
        transaction.commit();
    }

    @Override
    public void onDetailsInteraction(Uri uri) {

    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:configChanges="keyboardHidden|orientation|screenSize"
    android:id="@+id/activity_main"
    android:tag="portrait"
    tools:context="com.example.o2k.lab2naviedition.MainActivity">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/fragment_container">
    </FrameLayout>

</LinearLayout>

activity_main.xml (land)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:configChanges="keyboardHidden|orientation|screenSize"
    android:orientation="horizontal"
    android:id="@+id/activity_main"
    android:tag="landscape">

    <fragment android:name="com.example.o2k.lab2naviedition.OverviewFragment"
        android:id="@+id/overview_fragment"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent" />

    <fragment android:name="com.example.o2k.lab2naviedition.DetailsFragment"
        android:id="@+id/details_fragment"
        android:layout_weight="2"
        android:layout_width="0dp"
        android:layout_height="match_parent" />

</LinearLayout>

OverviewFragment.java

package com.example.o2k.lab2naviedition;

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.List;

public class OverviewFragment extends ListFragment {

    private OnOverviewInteractionListener mListener;
    private static Group[] groups = {new Group("group 1", "5"), new Group("group 2", "13"),
            new Group("group 3", "12"), new Group("group 4", "32"), new Group("group 5", "45")};

    public OverviewFragment() {
    }

    public static OverviewFragment newInstance(String param1, String param2) {
        OverviewFragment fragment = new OverviewFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        int layout = android.R.layout.simple_list_item_1;
        List<String> groupNames = new ArrayList();
        for (Group g: groups
             ) {
            groupNames.add(g.getName());
        }
        setListAdapter(new ArrayAdapter<String>(getActivity(), layout, groupNames));
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_overview, container, false);
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        mListener.onOverviewInteraction(position);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnOverviewInteractionListener) {
            mListener = (OnOverviewInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnOverviewInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    public interface OnOverviewInteractionListener {
        void onOverviewInteraction(int position);
    }

    public static Group[] getGroups() {
        return groups;
    }
}

DetailsFragment.java

package com.example.o2k.lab2naviedition;

import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class DetailsFragment extends Fragment {

    private OnDetailsInteractionListener mListener;
    private String groupName;
    private String groupInfo;

    public DetailsFragment() {
    }

    public static DetailsFragment newInstance() {
        DetailsFragment fragment = new DetailsFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_details, container, false);
        TextView groupNameTextView = (TextView)v.findViewById(R.id.groupNameText);
        TextView groupInfoTextView = (TextView)v.findViewById(R.id.groupInfoText);
        if (this.getArguments() != null) {
            groupName = this.getArguments().getString("groupName");
            groupInfo = this.getArguments().getString("groupInfo");
        } else {
            groupName = "<emptyNAME>";
            groupInfo = "<emptyINFO>";
        }
        groupInfoTextView.setText("No of members: "+groupInfo);
        groupNameTextView.setText(groupName);
        return v;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnDetailsInteractionListener) {
            mListener = (OnDetailsInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnDetailsInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    public interface OnDetailsInteractionListener {
        void onDetailsInteraction(Uri uri);
    }
}

1条回答
2楼-- · 2019-09-17 05:16

try using FrameLayouts instead of your custom fragments in the xml file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:configChanges="keyboardHidden|orientation|screenSize"
    android:orientation="horizontal"
    android:id="@+id/activity_main"
    android:tag="landscape">

    <FrameLayout
        android:id="@+id/overview_fragment"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent" />

    <FrameLayout
        android:id="@+id/details_fragment"
        android:layout_weight="2"
        android:layout_width="0dp"
        android:layout_height="match_parent" />

</LinearLayout>

in your way, you are creating each fragment twice. good luck :)

查看更多
登录 后发表回答