尝试用另一个片段替换 main_activity 片段 onbuttonclick

Trying to replace main_activity fragment with another fragment onbuttonclick

我主要是想在欢迎屏幕上制作一个按钮,单击该按钮会启动一个片段。

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/touch"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="me.alexoladele.quotebook.MainActivity">

    <TextView
        android:id="@+id/welcome_screen_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_gravity="center_horizontal|top"
        android:layout_marginTop="144dp"
        android:gravity="center"
        android:text="The QuoteBook hosts Kanye West quotes. Enjoy"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textSize="36dp" />

    <Button
        android:id="@+id/start_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_gravity="center_horizontal|bottom"
        android:layout_marginBottom="47dp"
        android:clickable="true"
        android:elegantTextHeight="false"
        android:enabled="true"
        android:text="Start!" />

</FrameLayout>

MainActivity.java:

public class MainActivity extends AppCompatActivity {
int count = 0;
final QuoteFragment quoteFragment = new QuoteFragment();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    Button startButton = (Button) findViewById(R.id.start_button);
    if (startButton != null)
        startButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              quoteFragment.startSecondFragment();

            }
        });



    }



}

quote_fragment.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_height="match_parent"     android:id="@+id/real_quote_frag">
<fragment
    android:id="@+id/quote_frag"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:name="me.alexoladele.quotebook.QuoteFragment"
    tools:layout="@layout/activity_main">
<TextView
    android:text="@string/tap_screen"
    android:id="@+id/quote"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fontFamily="sans-serif-medium"
    android:textSize="26sp"
    android:gravity="center"
    android:layout_gravity="center"
    android:textColor="#a6a6a6" />

<TextView
    android:text="@string/quotist_name"
    android:visibility="visible"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fontFamily="sans-serif-medium"
    android:textSize="26sp"
    android:gravity="center"
    android:textColor="#585858"
    android:layout_gravity="center_horizontal|bottom"
    android:id="@+id/person" />
</fragment>

QuoteFragment.java:

public class QuoteFragment extends Fragment {
int count = 0;

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

    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.quote_fragment, container, false);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    FrameLayout touch = (FrameLayout) getView().findViewById(R.id.touch);
    final TextView quoteText = (TextView)  getView().findViewById(R.id.quote);

    // Makes quotes array
    String[] quotes = {
            "Quotes Placeholder"
    };

    // Put quotes array into arraylist
    final List<String> quoteList = new ArrayList<>(Arrays.asList(quotes));

    //
    if (touch != null)
        touch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (count >= quoteList.size()) {
                    count = 0;
                }
                Quote q = new Quote("");
                q.setQuote(quoteList.get(count));

                quoteText.setText(q.getQuote());
                count++;
            }
        });

}

public void startSecondFragment() {
    QuoteFragment myFragment = new QuoteFragment();
    FragmentManager manager = getFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.replace(R.id.real_quote_frag, myFragment, "Quote");
    transaction.addToBackStack(null);
    transaction.commit();

    }
}

我收到这个错误:

 FATAL EXCEPTION: main
                                                                             java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.FragmentTransaction android.app.FragmentManager.beginTransaction()' on a null object reference
                                                                              at me.alexoladele.quotebook.QuoteFragment.startSecondFragment(QuoteFragment.java:91)
                                                                              at me.alexoladele.quotebook.MainActivity.onClick(MainActivity.java:23)
                                                                              at android.view.View.performClick(View.java:4756)
                                                                              at android.view.View$PerformClick.run(View.java:19761)
                                                                              at android.os.Handler.handleCallback(Handler.java:739)
                                                                              at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                              at android.os.Looper.loop(Looper.java:135)
                                                                              at android.app.ActivityThread.main(ActivityThread.java:5253)
                                                                              at java.lang.reflect.Method.invoke(Native Method)
                                                                              at java.lang.reflect.Method.invoke(Method.java:372)
                                                                              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:900)
                                                                              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:695)
                                                                              at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:114)Bridge.java:114)

谁能帮我找出我做错了什么,并指出更有效的处理方法?

问题

您没有将您的 QuoteFragment 附加到您的 MainActivity,这意味着您在 QuoteFragment 中的 getFragmentManager() 调用将 return 为空,因为它会本质上是调用它所附加的父 activity,在您的情况下,它将为 null,因此 NullPointerException。 (由于您的字段不够,仅保留对片段的引用)

更好的方法

事情是这样的,强烈建议(你真的应该让你的生活更轻松)从你的 Activity 管理你的 Fragment .

现在您正在 QuoteFragment 中进行 片段交易 ,而您应该在 MainActivity.

中进行管理

所以在你的 MainActivity:

中它会是这样的
Button startButton = (Button) findViewById(R.id.start_button);
    if (startButton != null)
        startButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startSecondFragment(); // start your fragment from MainActivity
        }
    });

// This method will be in charge of handling your second fragment
private void startSecondFragment() {
    FragmentManager manager = getFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.replace(R.id.real_quote_frag, quoteFragment, "Quote");
    transaction.addToBackStack(null);
    transaction.commit(); 
}

更新:

为了帮助您更好地理解,我的 activity 和片段结构如下所示:

activity_main.xml

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- The view where I place my fragment -->
    <FrameLayout
        android:id="@+id/fragmentContent"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

MainActivity.java 我替换片段的地方:

FragmentManager fragmentManager = getSupportFragmentManager();

// Note how I place my fragment into fragmentContent layout
fragmentManager.beginTransaction().replace(R.id.fragmentContent, fragment).commit();

fragment_layout.xml

请注意我如何使用单独的片段布局 xml 文件将 INTO fragmentContent 放入 `activity_main.xml1

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.forcasie.joelmin.Fragment.HomeFragment">

    <!-- TODO: Update blank fragment layout -->
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical">
        <TextView
            android:textStyle="bold"
            android:textSize="25sp"
            android:text="@string/homeMessage"
            android:gravity="center_horizontal"
            android:layout_marginTop="40dp"
            android:layout_gravity="center_horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        </LinearLayout>

</FrameLayout>

Fragment.java 其中我 SET 具有上述布局文件的片段的实际布局:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment

    return inflater.inflate(R.layout.fragment_layout, container, false);
}