我有一个包含许多片段的应用程序,当单击一个按钮时,我正试图从一个片段转到另一个片段。
我遇到的麻烦是startActivity(new Intent(HomeFragment.this, FindPeopleFragment.class));
package info.androidhive.slidingmenu;
import info.androidhive.slidingmenu.HomeFragment;
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.Toast;
public class HomeFragment extends Fragment {
public HomeFragment() {
}
ImageButton bSearchByLocation, bSearchByNumber;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View InputFragmentView = inflater.inflate(R.layout.fragment_home,
container, false);
bSearchByNumber = ((ImageButton) InputFragmentView
.findViewById(R.id.bSearchByLocation));
bSearchByLocation = ((ImageButton) InputFragmentView
.findViewById(R.id.bSearchByNumber));
bSearchByLocation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (v.getId() == R.id.bSearchByNumber) {
Toast.makeText(getActivity(), "1", Toast.LENGTH_SHORT)
.show();
startActivity(new Intent(HomeFragment.this, FindPeopleFragment.class));
}
}
});
bSearchByNumber.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (v.getId() == R.id.bSearchByLocation) {
Toast.makeText(getActivity(), "2", Toast.LENGTH_SHORT)
.show();
}
}
});
return InputFragmentView;
}
}
在我完成解决方案后,代码如下所示:
package info.androidhive.slidingmenu;
import info.androidhive.slidingmenu.HomeFragment;
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
public class HomeFragment extends Fragment {
public HomeFragment() {
}
ImageButton bSearchByLocation, bSearchByNumber;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View InputFragmentView = inflater.inflate(R.layout.fragment_home,
container, false);
bSearchByNumber = ((ImageButton) InputFragmentView
.findViewById(R.id.bSearchByLocation));
bSearchByLocation = ((ImageButton) InputFragmentView
.findViewById(R.id.bSearchByNumber));
bSearchByLocation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (v.getId() == R.id.bSearchByNumber) {
Toast.makeText(getActivity(), "1", Toast.LENGTH_SHORT)
.show();
startActivity(new Intent(getActivity(), FindPeopleFragment.class));
}
}
});
bSearchByNumber.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (v.getId() == R.id.bSearchByLocation) {
Toast.makeText(getActivity(), "2", Toast.LENGTH_SHORT)
.show();
}
}
});
return InputFragmentView;
}
}
但当我运行它时,应用程序崩溃并关闭。
这是我的AndroidManifest代码:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.androidhive.slidingmenu"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="info.androidhive.slidingmenu.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="info.androidhive.slidingmenu.FindPeopleFragment"></activity>
</application>
</manifest>
这是我的日志聊天:
顺便说一句。。。。我使用了这个surce代码并在上面工作:
http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer
最佳答案
在Fragment
中,您应该将宿主活动(上下文)获取为getActivity()
。请改为:
startActivity(new Intent(getActivity(), FindPeopleFragment.class));
在清单中声明
FindPeopleFragment
类:<activity
android:name="com.packagename.FindPeopleFragment" />
必须在清单文件中声明所有
Activities
(不是Fragment
)。另外,检查
FindPeopleFragment
是否扩展Activity
或FragmentActivity
。如果这扩展了Fragment
,请不要执行Intent
。您必须创建一个FragmentTransaction
来替换(或添加上面的)旧片段(HomeFragment)。更新
你实现这一目标的方法是错误的。您尝试启动一个新的
Activity
,在您的例子中,它是一个Fragment
,而不是一个活动(扩展片段)。为此,您可以:// call a method when click event
((MyFragmentActivity) getActivity()).replaceFragments();
然后,在
FragmentActivity
中,将方法设置为:// replace the fragment container with this method
public void replaceFragments() {
Fragment newFragment = new FindPeopleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, newFragment);
transaction.commit();
}
更新2
正如@squonk在评论和his answer中所说,我的上述回答是一个解决方案,但不是正确的。要获得真正正确的解决方案,您需要声明一个
Callback interface
并将Fragment
与任何Activity
关联起来。首先声明一个接口并将其附加到片段中的活动:
OnFragSelected mCallback;
public interface OnFragSelected {
public void OnFragSelected(int id);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallback = (OnFragSelected) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()+" must implement OnFragSelected interface..");
}
}
然后在单击事件中调用此项:
@Override
public void onClick(View v) {
mCallback.OnFragSelected(800);
}
最后,在片段活动中:
... implements HomeFragment.OnFragSelected {
Fragment newFragment;
@Override
public void OnFragSelected(int id) {
// example: id = 800
// ...
newFragment = new FindPeopleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, newFragment);
transaction.commit();
}
}
这样“更加灵活[…]多个活动现在可以嵌入您的片段,它们只需实现通信接口”。这很重要,因为“片段是可重用的,因此不依赖于特定的活动”。另外,如果您“在其他地方使用片段,则可以消除
RuntimeException
的风险,因为它是强类型的。”这个问题和这些关于Fragment 2 fragment communicating的答案可以告诉你区别。Here,你有谷歌的例子,这个答案:onAttach callback from fragment to activity也许你能想出来。