尝试用另一个片段替换 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);
}
我主要是想在欢迎屏幕上制作一个按钮,单击该按钮会启动一个片段。
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);
}