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

视频地址: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;//附属于某个节日的id
private 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值