【问题标题】:What is the right approach for calling fragment method from Activity?从 Activity 调用片段方法的正确方法是什么?
【发布时间】:2021-01-17 14:41:07
【问题描述】:

我正在使用寻呼机适配器,我想从活动中调用片段方法。我尝试使用回调接口,但我得到空指针异常,因为 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);
}

【问题讨论】:

    标签: java android android-studio android-fragments


    【解决方案1】:

    您可以使用 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)
            }
        }
    }
    

    【讨论】:

    • 您不应将 LiveData 用于“一次通话事件”,而应创建类似 SingleLiveEvent 的内容。
    • 我同意你的看法。我只是给他一个想法来解决他的问题。正如你所说,我们可以将我在回答中更新的类用于一次通话事件。
    【解决方案2】:

    您可以使用 SharedViewModel接口回调广播接收器,也可以使用 getSupportFragmentManager

    但问题是,在访问 Fragment 的视图时,您必须使用空检查来管理这些东西,因为如果 Fragment 被分离,将会给出NullPointerException

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-24
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      相关资源
      最近更新 更多