Android-节日短信送祝福(UI篇:1-主布局的基本实现)

来源:互联网 发布:移动网络初始密码 编辑:程序博客网 时间:2024/05/19 00:38

视频地址:http://www.imooc.com/learn/510

这次学习的内容,将会分为两个部分,这里先讲有关UI的部分。而且,Demo是在Android Studio上进行的。

相关素材及源码:
http://download.csdn.net/download/qq_22804827/9433691


首先新建一个Moudle,然后在Moudle中的build.gradle总添加好下面几个Library Dependency(括号内为涉及的内容):
com.android.support:design(FloatingActionButton,TabLayout)
com.android.support:support-v4(ViewPager,Fragment,FragmentPagerAdapter)
com.android.support:cardview-v7(CardView )
com.android.support:appcompat-v7(AppCompatActivity )

并且事先在AndroidMainfest.xml中添加好权限,免得到时候疏忽忘记了:

<uses-permission android:name="android.permission.SEND_SMS" /><uses-permission android:name="android.permission.WRITE_CONTACTS" /><uses-permission android:name="android.permission.READ_CONTACTS" /><uses-permission android:name="android.permission.READ_PHONE_STATE" />

而需要用到的自定义的Activity会通过Android Studio自动注册到AndroidMainfest.xml,这点就不要我们操心了。

另外还会涉及一个FlowLayout.java类,会在文章末尾的素材中提供。


结构目录图:这里写图片描述


开始之前先完成com.example.just.festival_sms.bean包中的内容(实体类中省略了成员变量的Getter和Setter):
1、节日实体类:Festival
成员变量:

private int id;private String name;private String desc;//对节日的描述private Date date;

构造函数:

public Festival(int id,String name) {        this.id=id;        this.name=name;}

2、短信实体类:Msg
成员变量:

private int id;private int festivalId;//附属于某个节日的idprivate String content;//短信内容

构造函数:

public Msg(int id, int festivalId, String content) {        this.id = id;        this.festivalId = festivalId;        this.content = content;}

3、为App提供需要模拟的数据的工具类FestivalLab

public class FestivalLab {    private static FestivalLab mInstance;    private List<Festival> mFestivals=new ArrayList<Festival>();    private List<Msg> mMsgs=new ArrayList<Msg>();    private FestivalLab() {        mFestivals.add(new Festival(1,"国庆节"));        mFestivals.add(new Festival(2,"中秋节"));        mFestivals.add(new Festival(3,"元旦"));        mFestivals.add(new Festival(4,"春节"));        mFestivals.add(new Festival(5,"端午节"));        mFestivals.add(new Festival(6,"七夕节"));        mFestivals.add(new Festival(7,"圣诞节"));        mFestivals.add(new Festival(8,"儿童节"));        initMsgsContent();    }    public void initMsgsContent() {        //自行在mMsgs中添加短信实例内容,例:        mMsgs.add(new Msg(2,1,"飞舞的彩带是我的关怀,喧天的锣鼓是我的祝福。国庆佳节到了,祝你全家红红火火,和和美美,开开心心!"));        ......    }    public static FestivalLab getInstance() {        if(mInstance==null) {            synchronized(FestivalLab.class) {                if(mInstance==null)                    mInstance=new FestivalLab();            }        }        return mInstance;    }    public List<Festival> getFestivals() {        return new ArrayList<Festival>(mFestivals);//返回一个副本,防止对原始的mFestivals造成修改,从而导致对FestivalLab的影响    }    public Festival getFestivalById(int id) {        for(Festival festival:mFestivals) {            if(festival.getId()==id) {                return festival;            }        }        return null;    }    public Msg getMsgByFestivalIdAndMsgId(int festivalid,int msgId) {        List<Msg> msgs=getMsgsByFestivalId(festivalid);        for(Msg msg:msgs)            if(msg.getId()==msgId)                return msg;        return null;    }    public List<Msg> getMsgsByFestivalId(int fesId) {        List<Msg> msgs=new ArrayList<Msg>();        for(Msg msg:mMsgs) {            if (msg.getFestivalId() == fesId)                msgs.add(msg);        }        return msgs;    }}

注意:在视频教学中,FestivalLab中有一个方法为getMsgById(int id),做用时根据传入的参数,也就是Msg的Id来返回相应的实例,但是这里我做了些许改动,变成了getMsgByFestivalIdAndMsgId(int festivalid,int msgId),因为我在mMsgs添加的Msg实例的id具有重复的且festivalId则不同,因此需要根据festivalIdI与msgId两个参数才能确定需要返回的Msg实例(因此在后面的UI篇3中的SendMsgActivity中的initViews方法中在得到Msg的实例时需要做出修改)。而视频中的只需要一个参数,那是因为所有的Msg实例的id是按照顺序来的,不存在重复值,所以可以直接根据id来返回相应的实例。


首先,先完成activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context=".MainActivity" >    <android.support.design.widget.TabLayout        android:id="@+id/id_tablayout"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:background="#ffffff"        app:tabGravity="fill"        app:tabIndicatorColor="#0ddcff"        app:tabMode="fixed"        app:tabSelectedTextColor="#0ddcff"        app:tabTextColor="#000000"/>    <!--可滑动的布局内容-->    <android.support.v4.view.ViewPager        android:id="@+id/id_viewpager"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1" /></LinearLayout>

主布局比较简单,就是TabLayout+ViewPager,在使用tabMode等属性时,涉及了一个新的系统命名空间:

xmlns:app="http://schemas.android.com/apk/res-auto"

这里写图片描述


接着是MainActivity.java

public class MainActivity extends AppCompatActivity {    private TabLayout mTabLayout;    private ViewPager mViewPager;    private String[] mTitles=new String[]{"节日短信","发送记录"};    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initViews();    }    private void initViews() {        mTabLayout= (TabLayout) findViewById(R.id.id_tablayout);        mViewPager= (ViewPager) findViewById(R.id.id_viewpager);        mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {            @Override            public Fragment getItem(int position) {                return new FetivalCategoryFragment();            }            @Override            public int getCount() {                return mTitles.length;            }            @Override            public CharSequence getPageTitle(int position) {                return mTitles[position];            }        });        mTabLayout.setupWithViewPager(mViewPager);//建立ViewPager与Tab的联系    }}

可以注意到MainActivity继承自AppCompatActivity,而非Activity,有关AppCompatActivity可以看看文章末尾的扩展内容。
并且,源码中的涉及了Fragment,应该导入的包为:
android.support.v4.app.Fragment而非android.app.Fragment

mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {            @Override            public Fragment getItem(int position) {                return new FestivalCategoryFragment();            }            @Override            public int getCount() {                return mTitles.length;            }            @Override            public CharSequence getPageTitle(int position) {                return mTitles[position];            }        });

这一部分代码是非常关键的,给ViewPager设置一个FragmentPagerAdapter(参照扩展内容3)适配器,而new FragmentPagerAdapter时需要传入一个FragmentManager类型的参数,该参数就可以通过AppCompatActivity类中的getSupportFragmentManager(Return the FragmentManager for interacting with fragments associated with this activity.)方法获得。
而在new的FragmentPagerAdapter中要实现三个覆盖方法,其中getItem中返回一个Fragment实例。FestivalCategoryFragment是自定义的继承自Fragment的类,用于在一个GridView中显示节日的类表。
如图:这里写图片描述
由于目前在getItem中返回的同一个FestivalCategoryFragment的实例,所以“节日短信”和“发送记录”都显示的是节日的类表。


扩展内容:
1、关于ViewPager与TabLayout的使用,可以阅读一下这篇博客:
http://www.jianshu.com/p/14d910b273ea

2、链接:https://www.zhihu.com/question/35709367/answer/64134667
来源:知乎
Activity 发展到3.0(大概)之后,可以使用fragment了,但是support v4 提供了1.6~3.0的fragment兼容,所以如果需要用兼容版的fragment,则需要继承support v4提供的FragmentActivity。而后一点点时间之后,3.0(大概)出现的ActionBar也被向前支持了,这次是出现在support v7里,如果需要使用兼容版的actionbar,则继承support v7提供的ActionBarActivity(它是继承FragmentActivity的)。再然后也就是去年年底到今年,5.0提供了很多很多新东西,于是support v7也更新了,出现了AppCompatActivity ,具体功能请自行查找。
https://blog.xamarin.com/android-tips-hello-appcompatactivity-goodbye-actionbaractivity/

3、FragmentPagerAdapter API:
http://blog.csdn.net/kaiwii/article/details/7823613

0 0
原创粉丝点击