【问题标题】:OnClickListener inside Fragment片段内的 OnClickListener
【发布时间】:2017-09-05 13:02:36
【问题描述】:

我有一个活动和两个片段。第一个是项目列表,第二个是详细视图。理想情况下,我想将 String id 从 Fragment 1 发送到 Fragment 2(单击项目时),以便对 API 执行新的详细信息查询。 但是,现在我很困惑,我只想了解在哪里设置 clicklistener。我试过了:

Fragment 1 的 onCreateView:

recyclerView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(activity,"Hello", Toast.LENGTH_SHORT).show();
                Log.v("Fragment1", "CLICK !? CLICK !? CLICK !?  ");
            }
        });

Fragment 1 的适配器 - onBindViewHolder

holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context,"Hello", Toast.LENGTH_SHORT).show();
                Log.v("Adapter", "CLICK !? CLICK !? CLICK !?  ");
            }
        });

我的 activity_main.xml 只是一个 FrameLayout,我有单独的 xml,只有 RecyclerView,每个片段都有模板 xml

RecyclerView:

<android.support.v7.widget.RecyclerView
    android:id="@+id/recycler_view"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"/>

我的片段 1 的线性布局中有这些(不确定是否相关)

android:clickable="true"
android:focusable="true"

谢谢!

【问题讨论】:

  • 您不能将变量从一个片段传递到另一个片段。实现它的唯一方法是将变量存储在您的活动中并在您的第二个片段中获取它。在 MainActivity 中使用 getter 和 setter,这样您就可以轻松地设置和获取变量。

标签: android android-fragments


【解决方案1】:

为了能够处理每个项目的点击,这是正确的解决方案:

Fragment 1 的适配器 - onBindViewHolder

holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context,"Hello", Toast.LENGTH_SHORT).show();
                Log.v("Adapter", "CLICK !? CLICK !? CLICK !?  ");
            }
        });

要将信息从片段发送到另一个片段,您必须使用更多来自适配器的活动。

例如,您可以使用接口作为侦听器:

AdpaterListener.java

public interface AdpaterListener {
    void onItemClick(String id);
}

在你的适配器中创建一个 AdapterListener 变量和一个 setter:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{

        ...
       // your variables 
       private AdapterListener mListener;  


        // your code


    @Override
    public void onBindViewHolder(ViewHolder Vholder,final int position){
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context,"Hello", Toast.LENGTH_SHORT).show();
                Log.v("Adapter", "CLICK !? CLICK !? CLICK !?  ");
                mListener.onItemClick(data.get(position).getId()  // you call the listener here
            }
        });

    }

    public void setAdapterListener(AdapterListener listener) {
        mListener = listener
    }
}

然后您的活动必须implementsAdapterListener,一旦创建适配器调用adapter.setAdapterListener(this) 将活动设置为侦听器。您将在以下活动中检索 id:

@Override
public void onItemClick(String id) {

}

为了将 id 传递给下一个片段,您可以在此处遵循一些好的做法来使用 Bundle Best practice for instantiating a new Android Fragment

希望这会有所帮助。

【讨论】:

  • 首先,感谢您花时间回答我的问题。我知道片段不应该直接交流,我告诉了我的导师。他问我为什么不知道(我猜想看看我是否知道),所以我觉得文档说得很好,所以它们可以重复使用等,而回答是你的片段在这种情况下不需要重复使用.所以从他的角度来看,我不需要活动。我的 Activity 也只有 onCreate() 方法。基本上,如果 savedInstance 为空,我使用 FragmentManager 并添加我的列表片段。这一切都来自 Activity,所以那里没有适配器。
  • 那么适配器在哪里?在第一个片段中?
  • 是的。在 onCreateView 中
  • 好的,所以这也是一样的,你创建上面的接口,你把你的片段implements这个接口设置为监听器,这是第一步,一旦完成我会你解释其余的
  • 我很抱歉,但我有 2 个愚蠢的问题。首先,接口是在单独的 java 文件中还是在 Adapter 中声明是否重要。而且(这很尴尬)我无法弄清楚示例中的“数据”是什么。
【解决方案2】:

为了重用 Fragment UI 组件,您应该将每个组件构建为一个完全独立的模块化组件,定义其自己的布局和行为。一旦定义了这些可复用的 Fragment,就可以将它们与一个 Activity 关联起来,并将它们与应用程序逻辑连接起来,从而实现整体的复合 UI。

您通常希望一个 Fragment 与另一个 Fragment 进行通信,例如根据用户事件更改内容。所有 Fragment 到 Fragment 的通信都是通过关联的 Activity 完成的。两个 Fragment 永远不应该直接通信。

Please read this official solution provided by google

【讨论】:

  • 首先,感谢您花时间回答我的问题。我知道片段不应该直接交流,我告诉了我的导师。他问我为什么不知道(我猜想看看我是否知道),所以我觉得文档说得很好,所以它们可以重复使用等,而回答是你的片段在这种情况下不需要重复使用.所以从他的角度来看,我不需要 Activity
  • 即使您不希望您的片段可重用,建议让通信贯穿您的活动。因为集中式通信总是比多点通信和管理它们更好、更容易。
【解决方案3】:

首先,制作一个界面。它将让活动在片段之间进行通信。在接口中,声明你的方法。

public interface Communicate {


    //create same method in your activity. You will not put any code here.

    public void onButtonPressed();

}

在您的主要活动中,您必须实现接口。

public class MainPanelScreen extends AppCompatActivity implements Communicate {

您必须在主活动中声明与在界面中声明的方法相同的方法。

//This code is put in the method's declaration in the main activity//
{....
FragmentOne fragOne = new FragmentOne();
FragmentTwo fragTwo = new FragmentTwo():
}.....
@Override
public void onButtonPressed() {




    //This gets the buttonNumber from the button click
    String temp = fragOne.getButtonNumberVariable();


    //this sends the results to the second fragment.
    //you have to declare this method and its code must be in the fragment.
    fragTwo.showButtonNumber(temp);


}

在第一个片段的 onActivityCreated() 中设置你的 onclicklistener。

Button btn = (Button) getView().findViewById(R.id.btn1);

    btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View view) {

            //Here you set the variable that you will get from the main activity.
            buttonNumberVariable = "1";

            //This is the interface being used to fire the method in the main activity. 
            Communicate cm; 
            cm.onButtonPressed();


        }
    });

【讨论】:

  • 首先,感谢您花时间回答我的问题。我知道片段不应该直接交流,我告诉了我的导师。他问我为什么不知道(我猜想看看我是否知道),所以我觉得文档说得很好,所以它们可以重复使用等,而回答是你的片段在这种情况下不需要重复使用.所以从他的角度来看,我不需要 Activity
  • 这里不是cm null 吗?
猜你喜欢
  • 2021-12-21
  • 1970-01-01
  • 1970-01-01
  • 2016-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-03
相关资源
最近更新 更多