1. 前言
1.最近笔者在实习,需要做一个炫酷的自定义日历来在满足实际项目的需求,当让这里不能把实际需求放在这里,不然我就那啥了,你懂的。
2.所以自己又重新设计了需求(内容完全不一样了,但UI有些类似),写了一个新的、十分炫酷的个性化日历,来记录您最近两个月的学习情况(记录您预期学习计划,以及实际完成的情况)。
3.这篇博客我会尽可能的详细的去创作,所以这对于新手来说提升会很大,包括我自己,我也是刚刚学习Android不久,其实刚拿到需求的时候,我根本不知道该如何下手,不怕你们笑话,我当时连自定义View都不太会,业务逻辑编写能力也是弱的不行,但最后我还是完成了,所以我在这里会穿插的分享一下我学习的方法以及学习的思路,希望感兴趣的朋友耐心的阅读,同时也希望您能够喜欢。
PS:由于篇幅和知识重点分布的特点,我把它拆分成了三个章节,一点一滴记录它是如何完成的,本Demo的推荐阅读顺序是:
【 ① —> ② —> ③ 】或者【 ② —> ③】,本章编号为“①”
相关参考链接:
2. 最终的效果图如下:
3. 本章简介
本章主要介绍的是本Demo的框架,其实就是一个ViewPager+fragment的经典用法,如果非常了解的话可以直接跳过本章节。
本章成果图
4. 本Demo框架具体实现
(1)设计UI以及基础编码
(1)首先把导航栏和状态栏给去掉
① 去掉导航栏:只要在res\values\styles.xml的下添加这两个属性就行了
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
我怎么知道是这样两行代码呢?你可以看看系统对于这样的情况是怎么实现的,你仿照来写就好了(到AndroidManifest配置文件中,找到APP的主题【@style/AppTheme】点击进去;然后找到AppTheme的父主题【Theme.AppCompat.Light.DarkActionBar】点击进去,搜索【NoActionbar】),如下图所示:
① 去掉状态栏:只要把状态栏的颜色变得和标题一样就行了,在MainActivity设置布局之前加上一行代码就好了:
getWindow().setStatusBarColor(getResources().getColor(R.color.colorStatusBar));
(2)然后在MainActivity的布局文件中写UI(【标题】,【ViewPager指示器】 和 【ViewPager】)
<LinearLayout
... ... ...>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="30dp"
android:background="#F7F8F8">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:text="记录"
android:textColor="#ED4E3C"
android:textSize="17sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_last"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@mipmap/bg_normal"
android:gravity="center"
android:text="5月"
android:textColor="#656565"
android:textSize="17sp" />
<TextView
android:id="@+id/tv_current"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@mipmap/bg_over"
android:gravity="center"
android:text="6月"
android:textColor="#F7F8F8"
android:textSize="17sp" />
</LinearLayout>
<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>
(3)创建两个fragment,分别来显示【当月学习记录(CurrentMonthFragment)】和【上月学习记录(LastMonthFragment)】,由于它们俩的布局文件就一个TextView就不展示了:
①【当月学习记录(CurrentMonthFragment)】
public class CurrentMonthFragment extends Fragment {
private View mView;
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (mView == null) {
mView = View.inflate(getActivity(), R.layout.fragment_current,null);
}
return mView;
}
}
②【上月学习记录(LastMonthFragment)】:
public class LastMonthFragment extends Fragment {
private View mView;
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (mView == null) {
mView = View.inflate(getActivity(), R.layout.fragment_last,null);
}
return mView;
}
}
(4)最后在MainActivity中初始化一下我们创建fragment:
public class MainActivity extends AppCompatActivity {
private CurrentMonthFragment mCurrentMonthFragment;
private LastMonthFragment mLastMonthFragment;
private List<Fragment> mFragments;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setStatusBarColor(getResources().getColor(R.color.colorStatusBar));
setContentView(R.layout.activity_main);
initData();
}
private void initData() {
mFragments = new ArrayList<>();
mCurrentMonthFragment = new CurrentMonthFragment();
mLastMonthFragment = new LastMonthFragment();
mFragments.add(mLastMonthFragment);
mFragments.add(mCurrentMonthFragment);
}
}
编写具体的业务逻辑
(1)首先找组件,这里使用的是Butterknife插件,如何使用呢
什么是Butterknife?
一句话:你再也不用写 【 findViewById() 】这么销魂的代码了!
①在gradle里面添加如下依赖:
//【ButterKnife】
compile 'com.jakewharton:butterknife:8.4.0'
compile 'com.jakewharton:butterknife-compiler:8.4.0'
②在AndroidStudio上安装butterknife的插件:
File—>settings—>Plunge下搜索到butterknife然后点击安装,它会提示你重启,然后你重启之后就可以使用了,如下图所示:
③如何使用:
在布局文件上方,右击选择 Generate—>Generate Butterknife Injections,然后选择需要用到的组件,有点击事件的把OnClick那边的选项也勾选上,如下图所示:
ps:一定要在布局文件的上方右击才有用哦!
(2)初始化viewpager的设配器
PS:首先显示的当前月的。
private void initAdapter() {
viewpager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
});
//首先显示当前月份
viewpager.setCurrentItem(1);
}
(3)初始化viewpager的监听器
private void initListener() {
viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if (position == 0) {
//设置当前月和上月viewpager指示器背景和颜色
tvLast.setBackgroundResource(R.mipmap.bg_over);
tvLast.setTextColor(getResources().getColor(R.color.colorStatusBar));
tvCurrent.setBackgroundResource(R.mipmap.bg_normal);
tvCurrent.setTextColor(getResources().getColor(R.color.colorBlack));
} else {
//设置当前月和上月viewpager指示器背景和颜色
tvCurrent.setBackgroundResource(R.mipmap.bg_over);
tvCurrent.setTextColor(getResources().getColor(R.color.colorStatusBar));
tvLast.setBackgroundResource(R.mipmap.bg_normal);
tvLast.setTextColor(getResources().getColor(R.color.colorBlack));
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
PS:我们只需要在ViewPager选中(onPageSelected)的时候做相应的逻辑:
(4)编写ViewPager指示器的点击事件:
@OnClick({R.id.tv_last, R.id.tv_current})
public void onClick(View view) {
switch (view.getId()) {
case R.id.tv_last://点击上一个月
viewpager.setCurrentItem(0);//设置为上一个月
break;
case R.id.tv_current://点击当前月
viewpager.setCurrentItem(1);//设置为当前月
break;
}
}
(4)让ViewPager指示器的【活】起来:
现在它显示的月份是固定的不变的,我们现在要它根据系统的时间自动的变化:
private void initTextView() {
//PS:mCalendar.get(Calendar.MONTH)的范围是(0~11)
int i = mCalendar.get(Calendar.MONTH) + 1;//i为当前月份值
int j = i - 1;
//设置当前月
tvCurrent.setText(i+"月");
//特殊情况,当前月为1月,j=i-1为0,没有0月,只有12月
if (j == 0) {
j = 12;
tvLast.setText(j+"月");
} else {
tvLast.setText(j+"月");
}
}
PS:注意Calendar对象初始化是这样的:
Calendar mCalendar = Calendar.getInstance();//初始化日历
到这基本上就完成了Demo的框架(ViewPager+Fragment经典框架)。
5. 本章小结
这是篇博文详细的记录了本Demo框架的搭建,之前也说了我会尽可能的详细的去创作,由于篇幅和知识重点分布的特点,我把它拆分成了三个章节,一点一滴记录它是如何完成的,中间会扩展一些东西,包括一些常用到的android开发技术,和我自己开发过程中遇到的问题,我都会提到,因为这样创作的话对于新手来说提升会很大,因为我自己也是新手,刚刚学习Android不久,没有太多的经验,所以大神勿喷噢O(∩_∩)O,接下来就是手把手分享如何写一个炫酷【自定义日历】的时候了。
PS:本Demo的推荐阅读顺序是:
【 ① —> ② —> ③ 】或者【 ② —> ③】,本章编号为“①”