[英]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
. 您还没有连接你的
QuoteFragment
您MainActivity
,这将意味着你的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.