试图从片段中调用我的活动中的方法。我想要片段给方法数据,并在方法返回时获得数据。我想实现类似于对静态方法的调用,但不使用静态,因为它会在活动中产生问题。

新的片段,所以我需要一个简单的和教学的解释!

谢谢!


当前回答

对于Kotlin,请尝试一下

class DataForm : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        Tasks(this).getData()
    }

    fun getResponse(response: String) {
        // code
    }
}

class Tasks(private val context: Any) {
    fun getData() {

        val getContext = (context as DataForm).activity
        val getFragment = (context as DataForm)

        val responseListener = Response.Listener<String> { response ->
            getFragment.getResponse(response)
        }

        val errorListener = Response.ErrorListener { error ->
            error.printStackTrace();
        }

        val stringRequest = StringRequest(Request.Method.GET, url, responseListener, errorListener)
        Volley.newRequestQueue(getContext).add(stringRequest)
    }
}

其他回答

您可能应该尝试将片段与活动解耦,以防您想在其他地方使用它。您可以通过创建您的活动实现的接口来做到这一点。

所以你会像下面这样定义一个接口:

例如,假设你想给活动一个String,并让它返回一个Integer:

public interface MyStringListener{
    public Integer computeSomething(String myString);
}

这可以在片段或单独的文件中定义。

然后你会让你的活动实现接口。

public class MyActivity extends FragmentActivity implements MyStringListener{

  @Override
  public Integer computeSomething(String myString){
   /** Do something with the string and return your Integer instead of 0 **/ 
   return 0;
  }

}

然后在你的片段中,你会有一个MyStringListener变量,你会在片段onAttach(Activity Activity)方法中设置监听器。

public class MyFragment {

        private MyStringListener listener;

        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            try {
                listener = (MyStringListener) context;
            } catch (ClassCastException castException) {
                /** The activity does not implement the listener. */
            }
        }

    }

edit(17.12.2015):onAttach(Activity Activity)已弃用,改用onAttach(Context Context),它按预期工作

第一个答案肯定有效,但它将当前片段与宿主活动结合在一起。如果你想在另一个活动中使用它,保持片段与宿主活动解耦是很好的做法。

我认为在片段初始化时传递活动实例是一个更好的方法。我像下面这样传递实例:

class FragmentSignUp : Fragment() {

    private lateinit var authActivity: AuthenticateActivity

    ...
    
    companion object {

        fun newInstance(a: AuthenticateActivity): FragmentSignUp {
            val fragment = FragmentSignUp()
            fragment.authActivity = a
            return fragment
        }
    }
}

现在,您可以使用传递的活动实例初始化片段,也可以调用活动中的任何公共方法。像下图:

val fragmentManager = supportFragmentManager
val fragment = FragmentSignUp.newInstance(this)

fragmentManager.beginTransaction().replace(R.id.authenticate_fragment, fragment, FragmentSignUp::class.java.simpleName)
            .commit()

你现在可以在你的片段中访问你的activity公共方法;就像我的例子:

authactivity.goToLogInFragment()

在Java中,你的片段类应该是:

public class FragmentSignUp extends Fragment {

    private AuthenticateActivity authActivity;

    public static FragmentSignUp newInstance(AuthenticateActivity a) {
        FragmentSignUp fragment = new FragmentSignUp();
        fragment.authActivity = a;
        return fragment;
    }
}

注意:我们也可以将活动直接注入到片段构造函数中。但在大多数情况下,我们应该避免这样做,因为它会导致一些运行时问题。

对于Kotlin开发人员

(activity as YourActivityClassName).methodName()

针对Java开发人员

((YourActivityClassName) getActivity()).methodName();

我已经尝试了这个线程中显示的所有方法,没有一个对我有效,试试这个。这对我很管用。

((MainActivity) getContext().getApplicationContext()).Method();

从碎片到活动:

((YourActivityClassName)getActivity()).yourPublicMethod();

从活动到片段:

FragmentManager fm = getSupportFragmentManager();

//if you added fragment via layout xml
YourFragmentClass fragment = (YourFragmentClass)fm.findFragmentById(R.id.your_fragment_id);
fragment.yourPublicMethod();

如果你通过代码添加片段,并且在添加片段时使用了标签字符串,请使用findFragmentByTag代替:

YourFragmentClass fragment = (YourFragmentClass)fm.findFragmentByTag("yourTag");