Android 开始片段活动

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22571713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:10:49  来源:igfitidea点击:

Start fragment activity

android

提问by Rabeea Qabaha

I have an application with many fragments, and am trying to go from one fragment to another when a button is clicked.

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

The part I'm having trouble with is startActivity(new Intent(HomeFragment.this, FindPeopleFragment.class));

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

after i do the solution the code look like this :

在我完成解决方案后,代码如下所示:

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;
}
}

but when i Run it , the application crash and closed. this is my androidmanifest code :

但是当我运行它时,应用程序崩溃并关闭。这是我的 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>

and this is my logchat: enter image description here

这是我的聊天记录: 在此处输入图片说明

by the way .... i use this surce code and work on it : http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer

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

回答by fllo

In Fragment, you should get the hosting activity (the context) as getActivity(). Try this instead:

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

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

Declare the FindPeopleFragmentclass in your manifest:

FindPeopleFragment在清单中声明类:

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

All Activities(not Fragment) must to be declare in your manifest file.

All Activities(not Fragment) 必须在您的清单文件中声明。

Also, check if FindPeopleFragmentextends Activityor FragmentActivity. If this extends Fragment, don't do an Intent. You must to make a FragmentTransactionto replace (or add above) your old Fragment (HomeFragment).

另外,检查是否FindPeopleFragment扩展ActivityFragmentActivity。如果这扩展了Fragment,请不要执行Intent. 您必须制作一个FragmentTransaction来替换(或在上面添加)您的旧片段 (HomeFragment)。



UPDATE

更新

You are wrong in the way to achieve this. You try to start a new Activitywhich, in your case, is a Fragmentand not an activity(extends Fragment). To achieve this, you can:

你在实现这一目标的方式上是错误的。您尝试开始一个新的Activity,在您的情况下,它是 aFragment不是 Activity (extends Fragment)。为此,您可以:

// call a method when click event
((MyFragmentActivity) getActivity()).replaceFragments();

Then, inside your FragmentActivity, set the method as:

然后,在您的 中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

更新2

As @Squonksaid in comment and also in his answer, my answer above is a solution but not the right one. To have a really proper solution, you need to declare a Callback interfaceand associate the Fragmentwith any Activity.

正如@Squonk在评论和他的回答中所说,我上面的回答是一个解决方案,但不是正确的。要获得真正合适的解决方案,您需要声明 aCallback interface并将 theFragment与 any相关联Activity

First declare an interface and attach it to your activity in your fragment:

首先声明一个接口并将其附加到您的片段中的活动:

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..");
    }
}  

Then call this in your on click event:

然后在您的点击事件中调用它:

@Override
public void onClick(View v) {
    mCallback.OnFragSelected(800);
}  

Finally, in your fragment activity:

最后,在您的片段活动中:

... 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();
    }

}  

This way "is more flexible [...] Multiple activities can now embed your Fragment, they just have to implement the communication interface". This is important because "your fragment is re-usable and therefore do not depend on that specific Activity". Also, if you "use the fragment elsewhere, you eradicate the risk of a RuntimeExceptionbecause it is strongly typed."

这种方式“更灵活 [...] 多个活动现在可以嵌入您的 Fragment,它们只需要实现通信接口”。这很重要,因为“您的片段是可重复使用的,因此不依赖于该特定 Activity。此外,如果您“在别处使用该片段,您就消除了 a 的风险,RuntimeException因为它是强类型的”。

This question and these answers about Fragment 2 fragment communicatingcan show you the difference. Here, you have the google example and this answer: onAttach callback from fragment to activitymight you to figure it out.

这个问题和这些关于Fragment 2 片段通信的答案可以告诉你不同之处。在这里,你有谷歌的例子和这个答案:onAttach 从片段到活动的回调你可能会弄明白。

回答by mike20132013

Do this to your intent :

按照您的意图执行此操作:

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

and add this to your manifest :

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

<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>

Add your activity to your manifest inside the applications tag.

将您的活动添加到应用程序标签内的清单中。

It should work now .. :)

它现在应该可以工作了.. :)

回答by Squonk

A Fragmentshould be modular, self-contained and reusable - it shouldn't know about other application components.

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

Don't start an Activitydirectly from a Fragment. Instead you should declare an interface which your parent Activityimplements. When you click a button in your Fragmentit should make a call to a method in the interface telling the parent Activitywhich button has been pressed. The parent Activitycan then start which ever Activityis needed.

不要Activity直接从 a开始Fragment。相反,您应该声明一个您的父级Activity实现的接口。当你点击一个按钮时,Fragment它应该调用接口中的一个方法,告诉父级Activity哪个按钮被按下。然后,父母Activity可以开始Activity需要的任何一个。

See Creating Event Callbacks

请参阅创建事件回调