ViewPager+TabLayout+Fragment

activity_main.xml
<LinearLayout android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/main_layout"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <androidx.viewpager.widget.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </androidx.viewpager.widget.ViewPager>

</LinearLayout>
MainActivity
public class MainActivity extends AppCompatActivity {
    private ViewPager mViewPager;
    private TabLayout mTabLayout;
    private List<Fragment> fragmentList;
    private List<String> tabList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mViewPager = (ViewPager) findViewById(R.id.view_pager);
        mTabLayout = (TabLayout) findViewById(R.id.tab_layout);
        initTitle(); //添加Tab
        initFragment();// 添加Fragment
        mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
            @NonNull
            @Override
            public Fragment getItem(int position) {
                return fragmentList.get(position);
            }

            @Override
            public int getCount() {
                return fragmentList.size();
            }

            @Nullable
            @Override
            public CharSequence getPageTitle(int position) {
                return tabList.get(position);
            }
        });
        mTabLayout.setupWithViewPager(mViewPager);
    }
    private void initFragment(){
        fragmentList = new ArrayList<>();
        fragmentList.add(new BlankFragment1());
        fragmentList.add(new BlankFragment2());
        fragmentList.add(new BlankFragment3());
    }
    private void initTitle(){
        tabList = new ArrayList<>();
        tabList.add("haha");
        tabList.add("lala");
        tabList.add("fafa");
    }
}

自定义LinerLayout

重写onFinishInflate() 和onVisibilityChanged()

public class TimeView extends LinearLayout {

    private TextView timeText;
    // 少构造方法,会报错
    public TimeView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    public TimeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    public TimeView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }
//当XML布局文件被布局加载完,所有子控件均被映射之后,才会回调这个方法
    @Override
    protected void onFinishInflate() {
        // TODO Auto-generated method stub
        super.onFinishInflate();

        timeText = (TextView) findViewById(R.id.text_view1);

        timeHandler.sendEmptyMessage(0);
    }

    private void refreshTime() {

        Calendar cal = Calendar.getInstance();
        String timeStr = String.format("%d:%d:%d", cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE),
                cal.get(Calendar.SECOND));
        timeText.setText(timeStr);

        //System.out.println("timeStr============>" + timeStr);
    }

    @Override
    protected void onVisibilityChanged(View changedView, int visibility) {
        // TODO Auto-generated method stub
        super.onVisibilityChanged(changedView, visibility);
		//对view的可见性进行判断
        if (getVisibility() == View.VISIBLE) {
            timeHandler.sendEmptyMessageDelayed(0, 1000);
        } else {
            timeHandler.removeMessages(0);
        }
    }

    private Handler timeHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            refreshTime();

            if (getVisibility() == View.VISIBLE) {
                // 每隔一秒给自己发送消息
                timeHandler.sendEmptyMessageDelayed(0, 1000);
            }
        };
    };

}

将自定义的LinerLayout添加到fragment的xml中,实现了一个fragment的时钟功能。

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fragment"
    tools:context=".BlankFragment1">

    <!-- TODO: Update blank fragment layout -->
    <com.thundersoft.tablayout.TimeView
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/text_view1"
            android:textSize="80sp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </com.thundersoft.tablayout.TimeView>

</FrameLayout>

View的生命周期方法

View的生命周期从构造方法开始依次执行以下几个方法,该View的可见性为默认值时:
(0)Constructors()

View在代码中被创建时调用第一种构造方法,View从layout中加载出来时会被调用第二种构造方法,其中XML中的属性也会被解析。
(1)onFinishInflate()

该方法当View及其子View从XML文件中加载完成后触发调用。通常是在Activity中的onCreate方法调用后调用。
(2)onVisibilityChanged()

该方法在当前View或其祖先的可见性改变时被调用。如果View状态不可见或者GONE,该方法会第一个被调用。
(3)onAttachedToWindow()

当View被附着到一个窗口时触发。在Activity第一次执行完onResume方法后被调用。
(4)onMeasure()

该方法确定View以及其子View尺寸大小时被调用。
5)onSizeChanged()

该方法在Measure方法之后且测量大小与之前不一样的时候被调用。
(6)onLayout()

该方法在当前View需要为其子View分配尺寸和位置时会被调用。
(7)onDraw(Canvas)

该方法用于View渲染内容的细节。
(8)onWindowFocusChanged()

该方法也可能在绘制过程中被调用,具体是在包含当前View的Window获得或失去焦点时被调用。此时可以设置代码中定义的View的一些LayoutParameter。

如果View进入了销毁阶段,肯定是会被调用的。
(9)onWindowVisibilityChanged()

该方法同上,具体是在包含当前View的Window可见性改变时被调用。
10)onDetachedFromWindow()

当View离开附着的窗口时触发,比如在Activity调用onDestroy方法时View就会离开窗口。和一开始的AttachedToWindow相对,都只会被调用一次。

因此可以总结为:

(1)在Activity的onCreate方法中加载View,View的onFinishInflate会被调用,继而Activity的生命周期执行到onResume方法之后View才被附着到窗口上,继而进行绘制工作,onMeasure、onSizeChanged 、onLayout、onDraw。这几个方法可能由于setVisible或onResume被调用多次,最后是Window失去焦点后的销毁阶段。

(2)onVisibilityChanged()方法在View是可见状态时如上所示时机调用,但是View的状态如果是不可见或者GONE时,是首先被调用的。如果是Invisible状态,View的创建到layout即结束,不会绘制出来。如果是GONE状态,View也会被加载并添加到Window,但是不会再Measure、Layout和Draw了。也就时说即使是GONE状态,销毁时一样有Detach的过程,即View的销毁过程和可见性无关。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值