7

これは 2 つの部分の問題です。私が持っているのは、ユーザーが別のフラグメントにあるボタンをタップすると、3'rd Fragment(FragmentC) が動的に追加される 3 Fragment レイアウトです。次に、追加された後、3番目のフラグメントには最大化/最小化するボタンがあります。

更新:ソリューションの最後にスクロール



問題 1:

3 番目のフラグメント (R.id.fragment_C) のコンテナーとして機能する FrameLayout の可視性属性を変更しようとしています。

コードが行うことになっているのは、もともと android:visibility = "gone" を含む XML を持つ別のフラグメントを生成することです。次に、ボタンをタップすると Fragment が追加され、可視性が VISIBLE に変わるとします。

これが以前に取り上げられたことは知っていますが、4時間かけて機能させようとした後、何が間違っているのかを尋ねることにしました。

問題 2:

3 番目のフラグメントが生成された後、最初の 2 つのフラグメントを非表示にし、3 番目のフラグメントが画面いっぱいになるようにする最小化/最大化ボタンがあります。

問題は、.setVisibility(View.GONE) を使用すると、最初の 2 つのフラグメントのビューが削除されないことです。これは以前にも取り上げられましたが、私のコードではなぜ機能しないのかわかりません。

これまでのコード(冗長で申し訳ありませんが、すべての詳細を含める方がよいと思いました):

main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:paddingLeft="0dp"
    android:paddingRight="0dp"
    android:orientation="vertical"
    >

    <FrameLayout
        android:id="@+id/fragment_A"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:background="#CCCCCC" 
        >
    </FrameLayout>

    <FrameLayout
        android:id="@+id/fragment_B"
        android:layout_width="fill_parent"
        android:layout_height="300dp"
        android:layout_below="@id/fragment_A"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="15dp"
        android:background="#B4B4B4"
        >
    </FrameLayout>

    <FrameLayout
        android:id="@+id/fragment_C"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_below="@id/fragment_B"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="0dp"
        android:background="#A3A3A3"
        android:visibility="gone"
        >
    </FrameLayout>

</RelativeLayout>

土地/main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal"
    android:paddingLeft="0dp"
    android:paddingRight="0dp" >

    <LinearLayout
        android:id="@+id/fragments_container"
        android:layout_width="fill_parent"
        android:layout_height="200dp"
        android:baselineAligned="false" >

        <FrameLayout
            android:id="@+id/fragment_A"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="0.5"
            android:background="#CCCCCC" >
        </FrameLayout>

        <FrameLayout
            android:id="@id/fragment_B"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="0.5"
            android:background="#B4B4B4"
             >
        </FrameLayout>
    </LinearLayout>

    <FrameLayout
        android:id="@+id/fragment_C"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_below="@id/fragment_container"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="0dp"
        android:background="#A3A3A3"
        android:visibility="gone" >
    </FrameLayout>

</RelativeLayout>

MainActivity.java

package com.example.android.fragments_proto.activity;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;

import com.example.android.fragments_proto.R;
import com.example.android.fragments_proto.fragment.GMC_DateSelectionFragment;
import com.example.android.fragments_proto.fragment.GMC_ProdUnitSelectionFragment;

public class MainActivity extends FragmentActivity {

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

        setContentView(R.layout.main_activity);

        FragmentManager fm = getSupportFragmentManager();

        Fragment fragmentA = fm.findFragmentById(R.id.fragment_A);

        Fragment fragmentB = fm.findFragmentById(R.id.fragment_B);

        if (fragmentA == null) {

            FragmentTransaction ft = fm.beginTransaction();
            ft.add(R.id.fragment_A, new FragmentA());
            ft.commit();
        }

        if (fragmentB == null) {

            FragmentTransaction ft = fm.beginTransaction();
            ft.add(R.id.fragment_B, new FragmentB());
            ft.commit();
        }
    }
}

これで、最初のフラグメントの XML ファイルと .java ファイルが作成されました。

fragment_A.xml

<?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:gravity="center_horizontal"
    >

    <DatePicker
        android:id="@+id/datePicker1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

FragmentA.java

package com.example.android.fragments_proto.fragment;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.DatePicker;
import android.widget.Toast;

import com.example.android.fragments_proto.R;

public class FragmentA extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_A, container, false);

        DatePicker datePicker = (DatePicker) view.findViewById(R.id.datePicker1);
        datePicker.setCalendarViewShown(true);
        datePicker.setSpinnersShown(false);            

        datePicker.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                 Activity activity = getActivity();

                    if (activity != null) {

                        Toast.makeText(activity, "You Touched ME!", Toast.LENGTH_SHORT).show();
                    }
            return false;
            }
        });

        return view;
    }
}

これで、タップ時に R.id.fragment_C にコンテンツを追加するボタンを含む Fragment の XML および .java ファイル

fragment_B.xml

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

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="0.1"
        >

        <ListView
            android:id="@+id/listView1"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            >
        </ListView>

    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:orientation="horizontal"
        android:gravity="center"
        android:layout_height="wrap_content">

            <Button
                android:id="@+id/button"
                android:text="@string/btn_fragment"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
            />

    </LinearLayout>

</LinearLayout>

FragmentB.java

package com.example.android.fragments_proto.fragment;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;

import com.example.android.fragments_proto.R;

public class FragmentB extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragmentB, container, false);

        ListView listView = (ListView) view.findViewById(R.id.listView1);
        Button button = (Button) view.findViewById(R.id.button);

        String[] machines = new String[] { "MachineId-001", "MachineId-002", "MachineId-003", "MachineId-004", "MachineId-005", "MachineId-006", "MachineId-007", "MachineId-008"};

        listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        listView.setAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.select_dialog_multichoice, machines));
        final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.fragment_C);

        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
               Activity activity = getActivity();

               if (activity != null) {
                   getFragmentManager().beginTransaction().replace(R.id.fragment_C, new FragmentC()).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).addToBackStack(null).commit();
                   frameLayout.setVisibility(View.VISIBLE);
                }
            }

        });

        return view;
    }

}

追加されるはずの Fragment の XML および .java ファイル。

fragment_C.xml

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

    <LinearLayout
        android:layout_width="fill_parent"
        android:orientation="horizontal"
        android:gravity="center"
        android:layout_height="wrap_content">

    <Button
        android:id="@+id/maximize_button"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Maximize Me!" />

    </LinearLayout>

    <TextView 
        android:id="@+id/text_view"
        android:textIsSelectable="true"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#FF33FF"
        />

</LinearLayout>

FragmentC.java

package com.example.android.fragments_proto.fragment;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import com.example.android.fragments_proto.R;

public class FragmentC extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_C, container, false);

        TextView textView = (TextView) view.findViewById(R.id.text_view);

            final Fragment fragmentA = getFragmentManager().findFragmentById(R.id.fragment_A);
            final Fragment fragmentB = getFragmentManager().findFragmentById(R.id.fragment_B);

            button.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    FragmentTransaction ft = getFragmentManager().beginTransaction();

                    if (fragmentA.isVisible() && fragmentB.isVisible()) {
                        ft.hide(fragmentA);
                        ft.hide(fragmentB);
                        fragmentA.getView().setVisibility(View.GONE);
                        fragmentB.getView().setVisibility(View.GONE);
                        button.setText("Minimize Me!");
                        ft.addToBackStack(null);
                    } else {
                        ft.show(fragmentA);
                        ft.show(fragmentB);
                        fragmentA.getView().setVisibility(View.VISIBLE);
                        fragmentB.getView().setVisibility(View.VISIBLE);
                        button.setText("Maximize Me!");
                        ft.addToBackStack(null);
                    }
                    ft.commit();
                }
            });     

        return view;

    }
}




Moesioのおかげで問題と解決策が見つかりました

問題:

私のエラーは、(FragmentB.javaで)ビューを見つけようとしていたことでした

final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.fragment_C);

この行は null を返していたため、コードが .setVisibility() を実行するはずのポイントに到達すると、アプリが. nullPointerException を返します。

FragmentC.javaでも同じことが起こりました(私の2つの問題は関連していました)。私のfindViewByIdがnullだったので、ビューは削除されませんでした!


解決:

getActivity .findViewById(R.id.your_view);でビューを検索するだけです。

4

2 に答える 2

5

FragmentB では、contentView にないビューを取得しようとしています

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_b, container, false);

    // this is in fragment_b layout
    ListView listView = (ListView) view.findViewById(R.id.listView1);
    Button button = (Button) view.findViewById(R.id.button);

    /* ... */
    // ****************************************
    // this is NOT in fragment_b layout, which causes null
    // ****************************************
    final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.fragment_C);

    /* ... */
}

試す:

    final FrameLayout frameLayout = (FrameLayout) getActivity().getWindow().findViewById(R.id.fragment_C);

一方、R.id.fragment_C は拡張され、MainActivity に設定されます。

さらに、追加のフラグを使用するまで同じ問題がありました

    FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    final Fragment fragmentC = new FragmentC();
    fragmentTransaction.add(R.id.fragment_C, fragmentC);
    fragmentTransaction.commit();
    menuIsOn = false;

    final View fragmentCView = findViewById(R.id.fragment_C);

    final Button btn = (Button) findViewById(R.id.btn);
    btnPowers.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            if (!menuIsOn) {
                fragmentCView.setVisibility(View.VISIBLE);
            } else {
                fragmentCView.setVisibility(View.INVISIBLE);
            }
            menuIsOn = !menuIsOn;
        }
    });
于 2013-03-20T11:33:04.063 に答える