android 学习笔记14- 项目实战 基类抽取 标题定义 界面滑动

1、抽取Activity基类:

为什么要抽取基类呢?因为每次都用到相同的东西就可以把相同的操作放到基类里面,可以复用

我们正常在activity的onCreate里面找控件添加事件,显示文本:每个组件基本都是这3步,所以抽基类

a,正常写法:
MainActivity.java: 
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button bt = (Button) findViewById(R.id.bt);//initView
        bt.setOnClickListener(new OnClickListener() {//initListener
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "this is a toast", 0).show();
            }
        });
        bt.setText("改变按钮");//initData
    }
}
这样写有一个不好的地方就是如果控件多了onCreate方法里面就会有很多的重复代码

b,抽基类后的写法:
将我们的MainActivity所在的包名修改 com.example.test.ui.activity , 再创建一个com.example.test.base用于存放抽取的基类BaseActivity
com.example.test.base/BaseActivity.java:
    public abstract class BaseActivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //定义好了抽象方法,调用
            initView();
            initListener();
            initData();
        }
        public abstract void initView();
        public abstract void initListener();
        public abstract void initData();
    }

com.example.test.ui.activity/MainActivity.java:
    public class MainActivity extends BaseActivity {
        private Button bt;
        @Override
        public void initView() {
            setContentView(R.layout.activity_main);
            bt = (Button) findViewById(R.id.bt);
        }

        @Override
        public void initListener() {
            bt.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    Toast.makeText(MainActivity.this, "this is a toast", Toast.LENGTH_SHORT).show();
                }
            });
        }

        @Override
        public void initData() {
            bt.setText("改变按钮");
        }
    }
这样我们就基本完成了基类的抽取,但是在MainActivity中的侦听我们也可以放到BaseActivity里面


c,优化后的抽基类:
com.example.test.base/BaseActivity.java:
    public abstract class BaseActivity extends Activity implements OnClickListener {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //定义好了抽象方法,调用
            initView();
            initListener();
            initData();
        }
        public abstract void initView();
        public abstract void initListener();
        public abstract void initData();
        public abstract void processClick(View v);//记住一定要带一个View参数,便于主activity判断是哪个View

        @Override
        public void onClick(View v) {
            processClick(v);//在主方法里面实现具体的侦听事件处理逻辑
        }
    }

com.example.test.ui.activity/MainActivity.java:
    public class MainActivity extends BaseActivity {
        private Button bt;
        @Override
        public void initView() {
            setContentView(R.layout.activity_main);
            bt = (Button) findViewById(R.id.bt);
        }

        @Override
        public void initListener() {
            //this就是MainActivity,它继承了BaseActivity,而父类实现了OnClickListener接口所以可以
            bt.setOnClickListener(this);
        }

        @Override
        public void initData() {
            bt.setText("改变按钮");
        }

        @Override
        public void processClick(View v) {//实现父类的点击处理的抽象方法
            switch (v.getId()) {
            case R.id.bt:
                Toast.makeText(MainActivity.this, "this is a toast",Toast.LENGTH_SHORT).show();
                break;
            }
        }
    }

这样优化就完成了,在android4.4模拟机上亲测OK

2、去掉界面的标题栏:

我们的应用一般都不想要自带的标题栏,太丑了,在代码里面也可以实现,但是每个activity都去写一遍,太麻烦
我们可以在清单文件定义一个主题
我们在style.xml中定义一个没有标题的style
    //系统调用的
    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    </style>
    //我们定义的
    <style name="AppTheme2" parent="@android:style/Theme.NoTitleBar">
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    </style>

但是有个问题,我们如果用了AppTheme2这个主题,那么系统AppTheme里面其它的属性我们就用不了了。
这个时候我们可以进入@android:style/Theme.NoTitleBar里面查看下 
里面的主要实现:
    <style name="Theme.NoTitleBar">
        <item name="android:windowNoTitle">true</item>//我们只需要这个就行
    </style>

最后我们只需要在系统主题里面加一个属性就行:
    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
        <item name="android:windowNoTitle">true</item>
    </style> 

这样就完成了所有的界面都没有标题的操作

3、实现主界面的tab选项点击切换,也可以滑动切换

滑动切换主要用到ViewPager这个控件
主要的实现方案有2种
ViewPager+Fragment ,一个主的activity里面加上Fragment
tabHost+ViewPager, 不过定义xml布局文件需要注意将FrameLayout的高度定为0dp,只要显示选项卡就行

ViewPager是在v4包里面的,所以写的时候不会有提示的
下面主要分析下ViewPager+Fragment的实现方法,沿用上面的分析代码:

a,定义activity_main.xml的布局文件
    这个和之前一样没有什么新的知识,主要就是用线性和相对布局组合来实现的。注意的一点就是ViewPager需要包名的路径
    为了能向下兼容,使用的是android.support.v4包
    activity_main.xml:
    <LinearLayout 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"
        tools:context=".MainActivity" 
        android:orientation="vertical"
        >
        <RelativeLayout 
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:background="#292C29"
            >
            <LinearLayout 
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="horizontal"
                >
                <!-- 会话 -->
                <LinearLayout 
                    android:id="@+id/ll_tab_conversation"
                    android:layout_width="0dp"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:orientation="vertical"
                    android:gravity="center"
                    >
                    <ImageView 
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:background="@drawable/img_conversation"
                        />
                    <TextView 
                        android:id="@+id/tv_tab_conversation"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="会话"
                        android:textColor="#FFFFFF"
                        android:textSize="14sp"

                        />
                </LinearLayout>
                <!-- 分组 -->
                <LinearLayout 
                    android:id="@+id/ll_tab_group"
                    android:layout_width="0dp"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:orientation="vertical"
                    android:gravity="center"
                    >
                    <ImageView 
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:background="@drawable/img_group"
                        />
                    <TextView 
                        android:id="@+id/tv_tab_group"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="分组"
                        android:textColor="#FFFFFF"
                        android:textSize="14sp"

                        />
                </LinearLayout>
                <!-- 搜索 -->
                <LinearLayout 
                    android:id="@+id/ll_tab_search"
                    android:layout_width="0dp"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:orientation="vertical"
                    android:gravity="center"
                    >
                    <ImageView 
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:background="@drawable/img_search"
                        />
                    <TextView 
                        android:id="@+id/tv_tab_search"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="搜索"
                        android:textColor="#FFFFFF"
                        android:textSize="14sp"

                        />
                </LinearLayout>
            </LinearLayout>
            <View 
                android:id="@+id/v_indicate_line"
                android:layout_width="60dp"
                android:layout_height="4dp"
                android:background="#CE0000"
                android:layout_alignParentBottom="true"
                />
        </RelativeLayout>
        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            ></android.support.v4.view.ViewPager>

    </LinearLayout>

b,定义一个Fragment基类:
    我们在界面ViewPager上面显示Fragment,所以我们先要把Fragment基类创建出来.
    所以我们先com.example.test.base包下定义一个BaseFragment基类继承Fragment,注意我们使用的是v4包的那个
    BaseFragment.java:
    public abstract class BaseFragment extends Fragment implements OnClickListener {
        //1-返回一个View对象,这个对象会作为Fragment的显示内容
        //2-注意我们填充哪个View不能在基类里面写死,我们要实现类中去填充。
        //3-所以我们要定义一个抽象的initView方法,便于实现类去实现
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            //5-这里我们就直接调用initView去返回一个填充的View对象
            return initView(inflater, container, savedInstanceState);
        }

        //4-定义这个抽象的方法时,类也需要时抽象的,不过可以通过ctrl+1提示完成,注意参数和onCreateView保持一致
        public abstract View initView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);

        //6-view对象的侦听和初始化数据也定义一个抽象的方法,调用的时机就时在FragmentActivity创建的时候调用,所以我们要重写下onActivityCreated方法
        public abstract void initListener();
        public abstract void initData();
        //10-定义一个抽象的方法在onClick里面调用,给子类实现逻辑
        public abstract void processClick(View v);//记得参数是View对象

        //7-重写onActivityCreated方法,调用initListener 和 initData 初始化侦听和数据
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            initListener();
            initData();
        }

        //8-我们Fragment里面有侦听,所以我们要像抽取基类一样也去实现下OnClickListener侦听接口,在类名上加 implements OnClickListener
        @Override
        public void onClick(View v) {
            //9-onClick里面的具体实现的逻辑是要子类实现的,所以我们定义一个抽象的方法去让子类实现
            processClick(v);
        }
    }

c,定义一个ViewPager的适配器
    ViewPager是一个ViewGroup,要实现切换是要有子节点的,这里不是addView,而是要设置一个adpter,和listView是一样的。
    所以我们先在com.example.test.adpter包下定义一个adpter
    MainPagerAdapter.java:

    public class MainPagerAdapter extends FragmentPagerAdapter {
        //3-定义一个framents用来保存传进来的需要显示的Fragment View对象
        List<Fragment> fragments ;

        //6-framents不可能自己创造,需要从外面传进来,所以在构造函数中添加参数
        public MainPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
            super(fm);
            this.fragments = fragments;
        }

        //1-返回的fragment对象会作为viewpager的条目,和ListViewAdpter里面的getView类似,系统调用。
        @Override
        public Fragment getItem(int position) {

            //5-返回Fragment View对象
            return fragments.get(position);
        }

        //2-我们不知道需要显示多少个Fragment的View对象,所以我们要创建一个集合,从外面传进来
        @Override
        public int getCount() {
            //4-返回有多少个Fragment View对象
            return fragments.size();
        }
    }


d,定义3个Fragment的布局文件
    我们要显示3个Fragment,所以需要3个布局文件,用于显示不同的界面
    fragment_conversatoin.xml  fragment_group.xml fragment_search.xml
    里面的内容自己定义,这里只显示一个模板,其它的复制粘贴就好了

    fragment_conversation.xml:
    <?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"
        android:orientation="vertical" >
        <TextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="会话"
            android:textSize="40sp"
            />
    </LinearLayout>

e,定义3个Fragment类,每个类就是一个tab下面显示的内容了
    现在我们的基类都创建好了,可以创建3个Fragment类了
    首先重新定义一个包 com.example.test.ui.fragment 里面再创建3个Fragment类

    ConversationFragment.java:演示一个类的写法,其它复制粘贴
    //1-创建的时候继承BaseFragment,自动就会生成下面4个方法需要实现
    public class ConversationFragment extends BaseFragment {

        @Override
        public View initView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            //2-填充布局文件,初始化会话的界面,返回的View对象就会给到基类的onCreateView返回
            View view = inflater.inflate(R.layout.fragment_conversation, null);
            return view;
        }

        @Override
        public void initListener() {
            // 暂时这3个方法先不写
        }

        @Override
        public void initData() {
            // TODO Auto-generated method stub
        }

        @Override
        public void processClick(View v) {
            // TODO Auto-generated method stub
        }
    }

d,MainActivity设置ViewPager的adpter(注意把BaseActivity里面改成继承FragmentActivity,不然拿不到FragmentManager)
    现在我们adpter创建好了,3个fragment的类也创建好了,可以new fragment对象和设置adpter了

    public class MainActivity extends BaseActivity {
        private ViewPager viewPager;
        private List<Fragment> fragments;

        @Override
        public void initView() {
            setContentView(R.layout.activity_main);
            //1-在xml中找到viewPager
            viewPager = (ViewPager) findViewById(R.id.viewPager);
        }

        @Override
        public void initListener() {

        }

        @Override
        public void initData() {
            //2-创建fragments 集合,定义一个全局变量
            fragments = new ArrayList<Fragment>();
            ConversationFragment fragment1 = new ConversationFragment();
            GroupFragment fragment2 = new GroupFragment();
            SearchFragment fragment3 = new SearchFragment();
            fragments.add(fragment1);
            fragments.add(fragment2);
            fragments.add(fragment3);

            //3-创建一个MainPagerAdapter,设置adapter
            //fm是一个FragmentManager,要获得FragmentManager需要基类去继承FragmentActivity,而不是继承Activity
            //这样才可以拿到FragmentManager
            MainPagerAdapter adapter = new MainPagerAdapter(getSupportFragmentManager(), fragments);
            viewPager.setAdapter(adapter);
        }

        @Override
        public void processClick(View v) {
        }
    }
到这里我们就可以实现了界面滑动的整个流程,测试OK。大体的框架已经   
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值