开始片段活动

时间:2014-03-22 00:13:25

标签: android

我有一个包含许多片段的应用程序,当点击一个按钮时,我试图从一个片段转到另一个片段。

我遇到问题的部分是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>

这是我的日志: enter image description here

顺便说一下....我使用这个代码并对其进行处理: http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer

3 个答案:

答案 0 :(得分:6)

Fragment中,您应该将托管活动(上下文)设为getActivity()。试试这个:

startActivity(new Intent(getActivity(), FindPeopleFragment.class));  

在清单中声明FindPeopleFragment类:

<activity
    android:name="com.packagename.FindPeopleFragment" />  

必须在清单文件中声明所有Activities(不是Fragment)。

另外,请检查FindPeopleFragmentActivity还是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();
}  

UPDATE2

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

}  

这样&#34;更灵活[...]多个活动现在可以嵌入你的片段,他们只需要实现通信接口&#34; 。这很重要,因为&#34;您的片段可以重复使用,因此不依赖于特定的活动&#34; 。此外,如果您&#34;在其他地方使用该片段,则可以消除RuntimeException的风险,因为它是强类型的。&#34;

这个问题和关于Fragment 2 fragment communicating的这些答案可以向您展示不同之处。 Here,你有谷歌的例子和这个答案:onAttach callback from fragment to activity你可能想出来。

答案 1 :(得分:1)

按照你的意图这样做:

startActivity(new Intent(getActivity(), FindPeopleFragment.class));

并将其添加到您的清单中:

<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="com.yourpackagename.FindPeopleFragment"></activity>
</application>

将您的活动添加到应用程序代码中的清单。

它现在应该工作.. :))

答案 2 :(得分:0)

Fragment应该是模块化的,自包含的和可重用的 - 它不应该知道其他应用程序组件。

不要直接从Activity开始Fragment。相反,您应该声明父Activity实现的接口。当您单击Fragment中的按钮时,它应该调用界面中的方法,告诉父Activity按下了哪个按钮。然后,父Activity可以启动,只需要Activity

请参阅Creating Event Callbacks