在自定义视图中访问片段引用

17

我有一个情景,其中Fragment在其布局中包含了一个自定义视图(通过扩展View类实现)。自定义视图需要访问Fragment的一些方法。但是我无法在自定义视图内部获取到Fragment引用。同时,我也找不到任何可以从自定义视图(作为Fragment的子元素)访问Fragment的方法。

根据Android-Fragment文档:我们可以在视图的构造函数中获取上下文。这个上下文是Activity的一个实例。但没有办法获取托管自定义视图的Fragment的引用。

请告诉我如何在自定义视图内部访问Fragment。

编辑:

添加代码以更好地理解我的问题:

MyFragment.java

public class MyFragment extends Fragment {

    int selectedOptionIndex;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    //get value of selectedOptionIndex from bundle and save it to this.selectedOptionIndex;

    }
    
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
    this.activity = activity;
        
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.myFragmentview, container, false);
        return view;
`//i can access views from fragment, but not vice versa.`
    }
    
}

myFragmentview.xml

    <com.test.CustomView
                android:id="@+id/myCustomView" android:layout_width="fill_parent"
                android:layout_height="40dip"  layout_weight="1"
                  />
        
public class CustomView extends View {
    
    private MyActivity context; 
    
    /** Default Constructor */
    public EasCalWeekViewHeader1(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
            this.context = (MyActivity) context;

// 现在使用 context,我们可以在此自定义视图中访问活动实例并调用任何其内部的方法。// 但我们无法为片段执行此操作。此时没有办法访问父片段。我无法访问 selectedOptionIndex 并将其设置在此视图中。// 如果视图可以访问父活动,则应该也可以访问父片段。
}

/** Default Constructor */
public EasCalWeekViewHeader1(Context context, AttributeSet attrs) {
    super(context,attrs);
            this.context = (MyActivity) context;
        }
    
}

}

5个回答

10

调用 FragmentManager.findFragment(this),其中 this 是你的自定义视图。

或者,如果你使用 Kotlin 的 Fragment 库 androidx.fragment:fragment-ktx,你可以在你的视图内直接使用扩展函数 View.findFragment()

该函数定义如下:

fun <F : Fragment> View.findFragment(): F = FragmentManager.findFragment(this)

根据文档:

此方法将定位与此视图关联的片段。 这是由 Fragment.onCreateView 返回的 View 和其子级自动填充的。


1
当您在开发自定义视图时,未指定片段的ID或标记时,我认为这是调用的最佳方法。我使用以下方法来获取托管我的自定义视图的片段或活动。val parent = try { // get fragment if we are in a fragment FragmentManager.findFragment<Fragment>(widget) } catch (exception: IllegalStateException) { // else get activity context }但是,您需要在gradle文件中添加implementation 'androidx.fragment:fragment-ktx:1.2.4' - SajithK

9

好的,用简单的语言来说:

根据Android Fragments的规定:我们可以在视图的构造函数中获取上下文。这个上下文的实例是Activity。但是没有办法获取托管自定义视图的Fragment的引用。

所以,上下文是Activity的实例,对吧?现在从这个Activity上下文中,如果您使用了字符串标记或ID为您的Fragment提供了一个标记或ID,那么我相信您可以通过findFragmentByTag(String tag)findFragmentById(int id)方法获取到Fragment的引用。

context.getFragmentManager().findFragmentByTag("tag_of_frag_you_are_trying_to_access");

HTH.


同意,这是访问任何视图内部片段的更好方式。 - Manish

2

我找到了解决方案并在我的项目中尝试

在自定义视图的构造函数中获取上下文的引用并将其转换为Activity类

private Activity activity ;
public EasCalWeekViewHeader1(Context context){
    activity = (Activity) context ; 
}

在你想调用Fragment方法的方法中,使用以下代码:
yourFragment a= activity.getFragmentManager().findFragmentById(R.id.fragment1);
a.YourMethod();

是的,我们可以使用getFragmentManager()访问片段。harikris和你的答案都可以接受。但是由于harikris的回答首先出现,我将其标记为被接受的答案。 - Manish

0
使用视图的构造函数将片段本身传递给它,而不是传递活动。这是一个深拷贝,因此您可以从视图中访问您的片段。
public class YourView extends View
{
     Fragment yourfragmentinside;
     public YourView(Fragment inputyourfragment)
     {
        this.yourfragmentinside = inputyourfragment
     }

}

不用担心,这是同一个片段——如果你不使用 new...()。


-1

我正在尝试使用findFragmentByTag来查找片段,但在我的项目中添加标记并不容易,而且该片段是一个自定义片段类。因此,我迭代片段来查找它。代码片段如下:

MyFragment myFrag = null;
List<Fragment> fragments = getContext().getSupportFragmentManager().getFragments();
for (Fragment frag : fragments) {
    if (frag instanceof MyFragment) {
        myFrag = (MyFragment) frag;
        break;
    }
}

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