简体   繁体   English

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

[英]Trying to replace main_activity fragment with another fragment onbuttonclick

I'm trying to make a button on the welcome screen essentially, that when clicked, starts a fragment. 我试图从本质上在欢迎屏幕上创建一个按钮,单击该按钮时将启动一个片段。

activity_main.xml: 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: 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: 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: 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();

    }
}

I get this error : 我收到此错误:

 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$1.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)

Can anybody help me figure out what I'm doing wrong, as well as point me to the more efficient way of handling this? 有人可以帮助我弄清楚我在做错什么,也可以指出更有效的处理方法吗?

The problem 问题

You have not attached your QuoteFragment to your MainActivity , this would mean your getFragmentManager() call in QuoteFragment will return null, because it would essentially make a call to the parent activity that it is attached to, which in your case would be null and hence the NullPointerException . 您还没有连接你的QuoteFragmentMainActivity ,这将意味着你的getFragmentManager()的调用QuoteFragment将返回null,因为这将从根本上提出其连接到父活动,而你的情况是零,因此通话NullPointerException (Simply holding a reference to the fragment as your field is not enough) (仅保留对片段的引用,因为您的字段还不够)

The better approach 更好的方法

Here's the thing, it is highly recommended (and you really should to make your life easier) that you manage your Fragment from your Activity . 事情就是这样, 强烈建议您(实际上应该使您的生活更轻松)从“ Activity管理“ Fragment

Right now your are doing Fragment transactions in your QuoteFragment , instead you should be managing it in your MainActivity . 现在,您正在QuoteFragment中进行Fragment事务 ,而应该在MainActivity进行管理。

So here's how it would look like, in your 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(); 
}

UPDATE: 更新:

To help you get a better understanding, here's how my activity and fragment structure looks like: 为了帮助您更好地理解,以下是我的活动和片段结构的样子:

activity_main.xml 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 where I replace my fragments: 我在其中替换片段的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 fragment_layout.xml

Note how I have a separate fragment layout xml file to place INTO fragmentContent in `activity_main.xml1 注意:我怎么有一个单独的片段布局的XML文件,将它放在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 where I SET the actual layout for the fragment with the above layout file: 在Fragment.java中 ,我使用上述布局文件设置片段的实际布局:

@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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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