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

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

谢谢!


当前回答

我一直在寻找最好的方法来做到这一点,因为不是每个方法,我们要调用位于片段与相同的活动父。

在你的碎片里

public void methodExemple(View view){

        // your code here

        Toast.makeText(view.getContext(), "Clicked clicked",Toast.LENGTH_LONG).show();
    }

在活动中

new ExempleFragment().methodExemple(context); 

其他回答

((YourActivityName) getActivity ()) .functionName ();

示例:((SessionActivity)getActivity()).changeFragment();

注意:类名应该是公开的

以下是我的做法:

首先制作接口

interface NavigationInterface {
    fun closeActivity()
}

接下来确保activity实现了接口并覆盖了接口方法

class NotesActivity : AppCompatActivity(), NavigationInterface {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_notes)
        setSupportActionBar(findViewById(R.id.toolbar))
    }

    override fun closeActivity() {
        this.finish()
    }
}

然后确保在片段中创建接口侦听器

private lateinit var navigationInterface: NavigationInterface

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
): View? {
    //establish interface communication
    activity?.let {
        instantiateNavigationInterface(it)
    }
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_notes_info, container, false)
}

private fun instantiateNavigationInterface(context: FragmentActivity) {
    navigationInterface = context as NavigationInterface
}

然后你就可以这样打电话了:

view.findViewById<Button>(R.id.button_second).setOnClickListener {
    navigationInterface.closeActivity()
}

从碎片到活动:

((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");

虽然我完全喜欢Marco的回答,但我认为指出你也可以使用基于发布/订阅的框架来实现相同的结果是公平的,例如,如果你使用事件总线,你可以做到以下几点

片段:

EventBus.getDefault().post(new DoSomeActionEvent()); 

活动:

 @Subscribe
onSomeActionEventRecieved(DoSomeActionEvent doSomeActionEvent){
//Do something

}

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

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

例如,假设你想给活动一个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),它按预期工作

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