Fragment需要处理on/off状态的ViewPager Fragment场景

ViewPager Fragment scenario where the Fragment need to handle on/off status

我有这个 ViewPager,它有 5 个 Fragment,我设置了 setOffscreenPageLimit(4)。现在,当应用程序启动时,所有五个 Fragments 都已加载。

Fragment nr 4 中,我想开始一个 Handler 延迟,每秒钟显示一些数据。我只想在用户 select 那个片段选项卡时启动它,并在用户转到另一个选项卡时停止 'Handler'。

我找不到直接的好方法来做到这一点。

我使用 greenrobot.eventbus 来完成这项工作,因为我知道 ViewPager 页面何时更改为 Fragment nr 4。我可以将事件发送到 Fragment nr 4.

但我觉得这很丑!

由于片段仅加载一次,我无法使用 onAttached() 启动 HandleronDetached() 停止 Handler

我为 'Fragment' 上的 'TextViews' 之一创建了一个 'getViewTreeObserver',当 'onGlobalLayout()' 触发时,'getVisibility()' 总是 'View.VISIBLE'即使我转到 'ViewPager'

中的其他选项卡

我还有哪些其他选择?

这是我所拥有的,它通过使用 greenrobot.eventbusFragment 是一个 PreferenceFragmentCompat 与此自定义 Preference

import android.content.Context;
import android.os.Handler;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceViewHolder;
import android.util.AttributeSet;
import android.widget.TextView;

import com.sunlux.smartpower.extended.R;
import com.sunlux.smartpower.extended.entity.EventOnViewPgaerTabChange;
import com.sunlux.smartpower.extended.utils.SettingsManager;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

public class ShowStatPreference extends Preference {

    private long MEGABYTE = 1024L * 1024L;
    private TextView bytesStat;
    private Handler mHandler;
    private boolean statRunning;
    /**
     * Timer for updating stat
     */
    private final Runnable statRunnable = new Runnable() {
        @Override
        public void run() {
            setStatBytes();
            if (statRunning) {
                startStatTimer();
            }
        }
    };

    public ShowStatPreference(Context context) {
        super(context);
    }

    public ShowStatPreference(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ShowStatPreference(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setWidgetLayoutResource(R.layout.show_stat_preference);
        mHandler = new Handler();
    }

    @Override
    public void onBindViewHolder(PreferenceViewHolder holder) {
        holder.itemView.setClickable(false); // disable parent click
        bytesStat = (TextView) holder.findViewById(R.id.bytes);
        super.onBindViewHolder(holder);
    }

    private void startStatTimer() {
        mHandler.postDelayed(statRunnable, 1000);
    }

    private void setStatBytes() {
        long bytes = Long.parseLong(SettingsManager.getByteSent());
        long mb = bytes / MEGABYTE;
        bytesStat.setText(getContext().getString(R.string.total_bytes, Long.toString(bytes), Long.toString(mb)));
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void workStart(EventOnViewPgaerTabChange event) {
        if (event.pos == 4) {
            if(statRunning){
                // prevent duplicate start
                return;
            }
            statRunning = true;
            startStatTimer();
        } else {
            statRunning = false;
        }
    }

    @Override
    public void onAttached() {
        EventBus.getDefault().register(this);
        super.onAttached();
    }

    @Override
    public void onDetached() {
        super.onDetached();
        EventBus.getDefault().unregister(this);
    }
}

有很多关于此的问题,但由于我不想访问 PreferenceFragmentCompat 而是访问其中的 Preference,我尝试传播来自 PreferenceFragmentCompat 的方法调用像这样

override fun setUserVisibleHint(isVisibleToUser: Boolean) {
    super.setUserVisibleHint(isVisibleToUser)
       // call Preference class ShowStatPreference and start the Handler

}

但无法找到访问 PreferenceFragmentCompat

的内部 class 的方法

你可以这样做:

ShowStatPreference myStat = findPreference(getString(R.string.pref_key_show_stat)) as ShowStatPreference