如何获取视图的父片段实例:

3

我有一个使用XML布局文件的片段,其中包含两个可点击的ImageView。 对于每个ImageView,我设置了一个onClick方法,例如:android:onClick="commentFragmentRemoveOnClick"。

在FragmentActivity(而不是Fragment)中,我这样定义:

public void commentFragmentRemoveOnClick(View v)
{

}

这个Fragment的类型是CommentFragment,它有一个public void getFragmentTag()方法来获取它的标签,我之前保存了它的标签。我需要获取图片被点击时所在的Fragment实例来获取它的标签。

我尝试过:

((CommentFragment)v).getParentFragment().getFragmentTag();

并且:

((CommentFragment)v).getParent().getFragmentTag();

但是Eclipse在这两个上面都给了我错误,应该如何正确地完成这个操作?
为了更清晰,这是我的CommentFragment:
public class CommentFragment extends Fragment {

private final static String TAG = CommentFragment.class.getSimpleName(); 
private String fragmentTag;
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); 
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.comment_fragment_layout,
            container, false);

    Bundle bundle = getArguments();
    String text = bundle.getString("comment");
    String fullUser = bundle.getString("user");
    String user = fullUser.substring(0, fullUser.indexOf("@"));
    String at = bundle.getString("at");

    TextView tvCmment = (TextView) rootView.findViewById(R.id.tvComment);
    TextView tvUser = (TextView) rootView.findViewById(R.id.tvUser);
    TextView tvAt = (TextView) rootView.findViewById(R.id.tvDate);

    tvCmment.setText(text);
    tvUser.setText(user);
    tvAt.setText(at);

    return rootView;
}

public void setText(String item) 
{
    TextView view = (TextView) getView().findViewById(R.id.tvComment);
    view.setText(item);
}

public void setFragmentTag(String tag)
{
    this.fragmentTag = tag;
}

public String getFragmentTag()
{
    return this.fragmentTag;
}
 }

以及布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/llCommentContainer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" 
    android:background="@drawable/try2">

   <TextView
       android:id="@+id/tvUser"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignLeft="@+id/tvComment"
       android:layout_alignParentTop="true"
       android:background="@color/my_gray"
       android:text="demo"
       android:textStyle="bold"
       android:paddingLeft="5dp"
       android:paddingRight="5dp"    
       android:textColor="@color/my_even_darker_gray" />

   <TextView
       android:id="@+id/tvComment"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentLeft="true"
       android:layout_below="@+id/tvDate"
       android:padding="5dp"
       android:text="This task is described in more details if you click on it."
       android:textColor="@color/my_even_darker_gray" />

   <TextView
       android:id="@+id/tvAt"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentTop="true"
       android:paddingRight="5dp" 
       android:textColor="@color/my_even_darker_gray"
       android:layout_toRightOf="@+id/tvUser"
       android:background="@color/my_gray"
       android:text="at" />

   <TextView
       android:id="@+id/tvDate"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_alignBaseline="@+id/tvAt"
       android:layout_alignBottom="@+id/tvAt"
       android:layout_toRightOf="@+id/tvAt"
       android:background="@color/my_gray"
       android:text="12/02"
       android:textColor="@color/my_even_darker_gray" />

    <ImageView
        android:id="@+id/iEdit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/tvComment"
        android:layout_marginRight="4dp"
        android:clickable="true"
        android:contentDescription="@drawable/add_comment_button"
        android:onClick="commentFragmentEditOnClick"
        android:src="@drawable/add_comment_button" />

    <ImageView
        android:id="@+id/iRemove"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/iEdit"
        android:layout_toRightOf="@+id/iEdit"
        android:layout_marginRight="4dp"
        android:clickable="true"
        android:contentDescription="@drawable/add_comment_button"
        android:onClick="commentFragmentRemoveOnClick"
        android:src="@drawable/add_comment_button" />

</RelativeLayout>

我希望能得到一些帮助。

谢谢。

3个回答

3

v不是Fragment的实例,这就是为什么Eclipse不喜欢你的代码。如果你想要一个fragment的实例,你必须使用FragmentManager和它的findFragmentByXXX方法之一。


我知道v不是一个片段,v是片段内的ImageView,我需要通过这个ImageView获取该片段的实例。我的片段是动态添加的,没有id,它们只有标签,我通过setFragmentTag和getFragmentTag分配给它们,现在正在尝试使用它们。 - Emil Adz
在这种情况下,您可以使用findFragmentByTag。此外,如果您知道v不是一个fragment,那么为什么要执行((CommentFragment)v)呢? - Cristian
你没有理解我的问题:为了使用FragmentManager的findFragmentByTag方法,我需要获取被点击视图所在的片段实例,并从中提取之前分配给它的标签。这就是我正在尝试做的事情,如果你仔细看,你会发现我正在尝试获取点击视图的父级,只是我不知道具体如何实现。 - Emil Adz
现在我明白了。那么...几个提示:尽量避免使用android:onClick,而是手动分配您的点击监听器。此外,如果您已经动态添加了片段,可以将片段的标签设置为图像视图的标签。这样,如果你想要包含所点击的ImageView的片段标记的片段,只需要执行'v.getTag()'即可。 - Cristian
更多背景信息:如果您在这里查看:http://stackoverflow.com/questions/15484530/removing-editing-fragments-that-were-add-dynamically,可能更清楚我想要实现什么。请再次查看问题,我已经添加了代码。所以如果我将标签设置为ImageView,我仍然必须使用getFragmentTag方法。没有办法获取它的实例吗?它是我单击的视图的容器,它们之间必须有一种连接可以使用。 - Emil Adz

3

我有一个通用的建议,可以解决你的问题并帮助你在未来 -

  1. 不要在xml文件中使用android:onClick,而是在代码中使用setOnClickListener - 尽可能避免将视图与应用程序的其他部分混合。

  2. 尽量使Fragment独立于其Activity。

如果图像是Fragment的一部分,为什么监听器是FragmentActivity的一部分呢?

在Fragment本身中使用setOnClickListener,您可能能够在应用程序的其他部分使用此Fragment,而不依赖于Activity。

这也可以解决识别单击图像所在的Fragment的问题。


谢谢@Pinhassi,但是如果你看一下我昨天作为答案提供的代码,那就是我所做的。但还是谢谢你的帮助,祝节日快乐:) - Emil Adz

0
为了获取被点击的ImageView所在的片段实例,我进行了以下操作:
在片段中,我为两个图像分别设置了onClickListeners,如下所示:
    iEdit = (ImageView)rootView.findViewById(R.id.iEdit);
    iEdit.setOnClickListener(new View.OnClickListener() 
    {
        @Override
        public void onClick(View v) 
        {
            Log.d(TAG, "pressed edit button");
            ((PicturesAndCommentsActivity) getActivity()).commentFragmentEditOnClick(fragmentTag);
        }
    });

    iRemove = (ImageView)rootView.findViewById(R.id.iRemove);
    iRemove.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) 
        {
            Log.d(TAG, "pressed remove button");
            ((PicturesAndCommentsActivity) getActivity()).commentFragmentRemoveOnClick(fragmentTag);
        }
    });

并且在片段活动中,我像这样定义了这两种方法:

public void commentFragmentRemoveOnClick (String tag)
{
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.remove(fragmentManager.findFragmentByTag(tag)).commit();
}

用于删除片段,现在我正在编辑该片段。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接