2016-04-24 118 views
0

我試圖在歡迎屏幕上製作一個按鈕,當點擊時,啓動一個片段。嘗試用另一個片段替換main_activity片段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$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) 

誰能幫我找出我做錯了什麼,以及點我處理這種更有效的方法是什麼?

回答

0

問題

您沒有連接您的QuoteFragmentMainActivity,這將意味着你的getFragmentManager()呼叫QuoteFragment將返回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(); 
} 

UPDATE:

爲了幫助你更好的理解,這是我的活動和片段結構的樣子:

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文件放置INTOfragmentContent在`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); 
} 
+0

我曾在之前的主要活動,但它無法找到ID之前。當我將它移回去時,我仍然得到這個錯誤:'java.lang.IllegalArgumentException:沒有找到id爲0x7f0c0060(me.alexoladele.quotebook:id/real_quote_frag)的片段QuoteFragment {3dc711f3#0 id = 0x7f0c0060 Quote}' –

+0

我不確定'real_quote_frag'來自哪裏,但是嘗試使用'R.layout.quote_fragment'而不是 –

+0

當我爲事務進行替換時,它要求將ID作爲第一個參數,這就是爲什麼我要real_quote_frag,它說它無法找到它的ID。當我點擊開始按鈕時,我希望屏幕切換quote_fragment –