android - 如何使用 Butterknife 获取 fragment xml 的引用

标签 android android-fragments butterknife

是否可以通过接口(interface)获取SomeFragment?我不想使用 FragmentManager,因为在我的原始代码中 MainActivity 是一个 fragment 。

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.some_container)
    FragmentCallback fragment;

    public interface FragmentCallback {
        void test();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        fragment.test();
    }
}

public class SomeFragment extends Fragment implements FragmentCallback {

    public SomeFragment() {
    }

    @Nullable
    @Override
    public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle
            savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_some, container, false);
        ButterKnife.bind(this, view);
        return view;
    }

    @Override
    public void test() {
        Log.d("" , "it works");
    }
}

布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    <fragment
            android:id="@+id/some_container"
            android:name="com.tamtam.myapplication.SomeFragment"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
</LinearLayout>

FATAL EXCEPTION: main Process: com.tamtam.myapplication, PID: 29138 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tamtam.myapplication/com.tamtam.myapplication.MainActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'void com.tamtam.myapplication.MainActivity$FragmentCallback.test()' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) at android.app.ActivityThread.-wrap12(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6119) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void com.tamtam.myapplication.MainActivity$FragmentCallback.test()' on a null object reference at com.tamtam.myapplication.MainActivity.onCreate(MainActivity.java:21) at android.app.Activity.performCreate(Activity.java:6679) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)  at android.app.ActivityThread.-wrap12(ActivityThread.java)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:154)  at android.app.ActivityThread.main(ActivityThread.java:6119)

最佳答案

这是不可能的,因为

Fragment 不是View,Butterknife 的@BindView 用于绑定(bind)View,而不是Fragment。

您可以使用 FragmentManager.findFragmentById(int id); 来获取 fragment ,但是如果您检查实现,您会发现 FragmentManager 看起来不像在 View 层次结构中

public Fragment findFragmentById(int id) {
    if (mAdded != null) {
        // First look through added fragments.
        for (int i=mAdded.size()-1; i>=0; i--) {
            Fragment f = mAdded.get(i);
            if (f != null && f.mFragmentId == id) {
                return f;
            }
        }
    }
    if (mActive != null) {
        // Now for any known fragment.
        for (int i=mActive.size()-1; i>=0; i--) {
            Fragment f = mActive.get(i);
            if (f != null && f.mFragmentId == id) {
                return f;
            }
        }
    }
    return null;
}

如果你想用 ButterKnife 做到这一点

您可以通过添加此功能来扩展 ButterKnife,或者您可以围绕它创建一个包装器并寻找您自己的注释。例如,您可以创建自定义注释

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BindFrament {
    @IdRes int value();
}

使用bind(Activity) 方法创建一个包装器,调用ButterKnife.bind(Activity) 方法然后寻找您自己的注解并将其设置到实例字段

public class ButterKnifeWrapper {

    public static void bind(Activity activity){
        ButterKnife.bind(activity);

        Class clazz = activity.getClass();
        for(Field field : clazz.getDeclaredFields()){
            if(field.isAnnotationPresent(BindFrament.class)){
                Class fieldType = field.getType();
                if(Fragment.class.isAssignableFrom(fieldType)){
                    int fragmentId = field.getAnnotation(BindFrament.class).value();
                    Fragment fragment = activity.getFragmentManager().findFragmentById(fragmentId);
                    try {
                        field.set(activity, fragment);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

然后在您的 Activity 中您可以这样做

public class MyActivity extends AppCompatActivity {

    @BindFrament(R.id.my_fragment)
    MyFragment myFragment;

    @BindView(R.id.my_view)
    View myView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_activity);
        ButterKnifeWrapper.bind(this);
    }
}

关于android - 如何使用 Butterknife 获取 fragment xml 的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45735848/

相关文章:

java - 空指针引用android java

Fragment 之间的 Android Tab 导航

android - android studio 操作栏中的抽屉导航覆盖了我的文本内容

android - 无法在启用混淆器的情况下构建发布版本

android - 为什么 ButterKnife 对 @OnClick 方法使用 DebouncingOnClickListener?

java - IntelliJ IDEA - 显示异常跟踪

android - 更改 TabHost 内的 View (一个 Activity ,多个 View )

android - 使用react-native测量音频的响度

android - 如何在 fragment 中实现 ImageView 的 OnClickListener?

android - ButterKnife ViewBinder 类在使用 Jack 时被丢弃