首页 > 解决方案 > 从 Activity 调用片段方法的正确方法是什么?

问题描述

我正在使用寻呼机适配器,我想从活动中调用片段方法。我尝试使用回调接口,但我得到空指针异常,因为 Fragment fragment = new Fragment() 没有调用该片段的 onCreate() 。有什么想法我应该怎么做?这是我的代码:

主要活动:

public interface Communicator {
    void passStatus(String status);
}

private Communicator communicator;

public void setCommunicator(Communicator communicator)
{
    this.communicator = communicator;
}

@Override
protected void onPause() {
    super.onPause();
    if(communicator != null)
    {
        communicator.passStatus("STOP");
    }
}

@Override
protected void onResume() {
    super.onResume();
    if(communicator != null)
    {
        communicator.passStatus("START");
    }
}

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

    tabLayout = findViewById(R.id.tabBar);
    viewPager = findViewById(R.id.viewPager);

    Fragment fragment = new Fragment();
    setCommunicator(new Communicator() {
        @Override
        public void passStatus(String status) {
            if(status == "START")
            {
                fragment.Start();
            }
            else if(status == "STOP")
            {
                fragment.Stop();
            }
        }
    });

    PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager());
    pagerAdapter.addFragment(fragment, "Some fragment");
    pagerAdapter.addFragment(new AnotherFragment(), "Another fragment");
    
    viewPager.setAdapter(pagerAdapter);
    tabLayout.setupWithViewPager(viewPager);
}

标签: javaandroidandroid-studioandroid-fragments

解决方案


您可以使用 SharedViewModel :https ://developer.android.com/topic/libraries/architecture/viewmodel#sharing

您将在活动中创建 SharedViewModel 并导出 LiveData 以用于启动或停止。在您的片段中,您将观察 SharedViewModel 的 LiveData。

一个呼叫事件的类:

import androidx.lifecycle.Observer

open class Event<out  T>(private val content: T) {

    @Suppress("MemberVisibilityCanBePrivate")
    var hasBeenHandled = false
        private set // Allow external read but not write

    /**
     * Returns the content and prevents its use again.
     */
    fun getContentIfNotHandled(): T? {
        return if (hasBeenHandled) {
            null
        } else {
            hasBeenHandled = true
            content
        }
    }

    /**
     * Returns the content, even if it's already been handled.
     */
    fun peekContent(): T = content
}

class EventObserver<T>(private val onEventUnhandledContent: (T) -> Unit) : Observer<Event<T>> {
    override fun onChanged(event: Event<T>?) {
        event?.getContentIfNotHandled()?.let {
            onEventUnhandledContent(it)
        }
    }
}

推荐阅读