Android 自定义布局的日历代码
系统自带的日历虽然好用,但是不符合某些项目的需求,所以需要自定义布局,看网上许多自定义View完成自定义日历的,
自认水平不够,无法驾驭,所以采用gridview来实现。
效果
CalendarUtils:(获取当前年月对应的数据数组)
package kyle.com.zujian;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
/**
* Created by kyle on 2016/8/12 0012.
* 获取某年某月的日期,界面上第一天为周日
* 通过传的年和月,获取对应年月的日期和第一天是周几
*/
public class CalendarUtils {
private static int FIRST_DAY_OF_WEEK;//第一天
private static Calendar calendar;//日历
public static List<DateEntity> getDate(int year, int month) {
if (year <= 0 || month < 1 || month > 12) {
return new ArrayList<>();//当年和月不符合规则时,返回空list
}
List<DateEntity> dates = new ArrayList<>();
calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);//设置年
calendar.set(Calendar.MONTH, month - 1);//设置月
calendar.set(Calendar.DAY_OF_MONTH, 1);//设置第一天
FIRST_DAY_OF_WEEK = calendar.get(Calendar.DAY_OF_WEEK) - 1;//获得第一天是周几 0:周日 6周六
for (int i = 0; i < FIRST_DAY_OF_WEEK; i++) {//假设是周日则跳过,假设不是周日,就添加对应数目的空白item
DateEntity entity = new DateEntity();
dates.add(entity);
}
int count = checkDays(year, month);//获取当前年月的天数
for (int i = 0; i < count; i++) {
DateEntity entity2 = new DateEntity(year, month, i + 1);
dates.add(entity2);
}
return dates;
}
/***
* 判断当前年月有多少天
*
* @param year
* @param month
* @return
*/
private static int checkDays(int year, int month) {
if (year < 1 || month > 12 || month < 1) {
return 0;
}
switch (month) {
case 2:
if (year % 4 == 0) {
return 29;
} else {
return 28;
}
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return 31;
case 4:
case 6:
case 9:
case 11:
return 30;
}
return 0;
}
}
实体类:DateEntity
package kyle.com.zujian;
/**
* Created by Administrator on 2016/8/9 0009.
*/
public class DateEntity {
private int year;
private int month;
private int day;
@Override
public String toString() {
return "DateEntity{" +
"year=" + year +
", month=" + month +
", day=" + day +
'}';
}
public DateEntity(){
}
public DateEntity( int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
}
CalendarGridView:(自定义的gridview,把代码转移到这里面,方便调用.)
package kyle.com.zujian;
import android.content.Context;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
/**
* Created by kyle on 2016/8/15 0015.
* 自定义日历gridview
*/
public class CalendarGridView extends GridView {
private Context mContext;
private List<DateEntity> mList = new ArrayList<>();
private MyAdapter mAdapter;
private Calendar calendar;
/***
* 今天
*/
private int NOW_YEAR;//当前年
private int NOW_MONTH;//当前月
private int NOW_DAY;//当前日
public CalendarGridView(Context context) {
super(context, null);
mContext = context;
}
public CalendarGridView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
calendar = Calendar.getInstance();//获取日历实例
NOW_YEAR = calendar.get(Calendar.YEAR);//当前年
NOW_MONTH = calendar.get(Calendar.MONTH) + 1;//当前月
NOW_DAY = calendar.get(Calendar.DAY_OF_MONTH);//当前日
mAdapter = new MyAdapter();//实例化和设置适配器
setAdapter(mAdapter);
}
public void init(int year, int month) {
if (year < 1 || month < 1 || month > 12) {
Toast.makeText(mContext, "年份或月份错误!", Toast.LENGTH_SHORT).show();
return;
}
mList.clear();
for (DateEntity entity : CalendarUtils.getDate(year, month)) {
mList.add(entity);
}
mAdapter.notifyDataSetChanged();
}
private class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
return mList.size();
}
@Override
public Object getItem(int position) {
return mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
MyHolder holder;
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.item_grid, null);
holder = new MyHolder();
holder.llMain = (LinearLayout) convertView.findViewById(R.id.ll_main);
holder.tvDate = (TextView) convertView.findViewById(R.id.tv_date);
holder.tvCount = (TextView) convertView.findViewById(R.id.tv_count);
convertView.setTag(holder);
} else {
holder = (MyHolder) convertView.getTag();
}
int year = mList.get(position).getYear();
int month = mList.get(position).getMonth();
int day = mList.get(position).getDay();
if (year == NOW_YEAR && month == NOW_MONTH && day == NOW_DAY) {
holder.llMain.setBackgroundResource(R.color.red);
holder.tvDate.setTextColor(ContextCompat.getColor(mContext, R.color.white));
holder.tvCount.setTextColor(ContextCompat.getColor(mContext, R.color.white));
} else {
holder.llMain.setBackgroundResource(R.color.white);
holder.tvDate.setTextColor(ContextCompat.getColor(mContext, R.color.black));
holder.tvCount.setTextColor(ContextCompat.getColor(mContext, R.color.black));
}
if (day != 0) {
holder.tvDate.setText(mList.get(position).getDay() + "");
} else {
holder.tvDate.setText("");
}
return convertView;
}
}
private class MyHolder {
private LinearLayout llMain;
private TextView tvDate;
private TextView tvCount;
}
}
在Activity里面这样调用:
CalendarGridView mGv= (CalendarGridView) findViewById(R.id.gv);
mGv.init(2016,8);
当然,布局和实体类都可以自己去根据需求写,而如果想要真正的日历功能,则可以使用viewpager+fragment实现了
下面我们一起来看一篇关于Android 用户登录 cookie 管理设计与实现例子,希望这篇文章能够帮助到各位朋友。功能需求
基本上每个社交 APP 都有其账号体系或者是允许允许用户第三方登录。用户登录成功后,APP 应该记录用户登录状态,用户退出后再登录就不再需要输入密码与账号了。
实现设计
服务端登录成功后返回注册用户信息
客户端在成功回调中将用户信息持久化记录到硬盘中
使用数据库存储用户信息,这里我使用了第三方库 ActiveAndroid
对 Bean 类进行封装,对用户敏感信息进行加密
每次登录时预先检查用户是否登录,如是,直接跳过登录界面
在 Application 类中维持一个用户登录状态的应用,便于程序动态调用
RESTful 接口
代码如下 | 复制代码 |
服务端 // local ['email', 'password', 'is_third'] // third ['uid', 'is_third'] @Table(name = "account") private final static int NO_ACCOUNT = 0; @Expose public AccountBean(User user){ public static void cacheAccountInfo(User user){ public static void logoutAccount(){ public static boolean existAccountCache(){ public static long getAccountID(){ public static List<AccountBean> getAllAccounts(){ } |
移动端Application 子类
代码如下 | 复制代码 |
public class ColorTalkApp extends Application { public static AccountBean sAccount = null; public static int getLoginedUserID(){ } |
服务端 UserRepository
代码如下 | 复制代码 |
public function loginIntoSystem($payload){ private function localAccountRegister($email, $password){ private function thirdAccountRegister($uid){ |
服务端 User 类
代码如下 | 复制代码 |
public static function isAccountRegistered($email) public static function isThirdAccountRegisted($uid){ public static function isAccountValid($email, $password) public static function isThirdAccountValid($uid) public static function getThirdUserByUid($uid){ public static function getLocalUserByEmail($email){ |
缘由
RecyclerView item可以实现滑动的监听,可以允许用户左滑动右滑动消失,也允许用户点击item。 分别需要重载onTouch与onClick方法,但两者时间会冲突,onClick会消费掉事件,导致事件不会传递到onTouch中。解决方法是将onClick的逻辑移动到onTouch中。
判定条件
参考资料1,使用了时间与移动距离两个变量要确保用户的确是想要点击item。满足这个条件将会调用onClick里的逻辑,否则滑动逻辑将被调用。时间控制在1s内, 思路是在ACTION_DOWN中记一个按下按钮的时间,在ACTION_UP判断是否ACTION_UP到ACTION_DOWN需要的时间小不小于1s;距离是衡量值是从ViewConfiguration这个类中取出来的,是安卓推荐的数据。
具体代码
private static final int MAX_CLICK_DURATION = 1000;
private int mSlop;
private long pressStartTime;
private float pressedX;
private float pressedY;
...
ViewConfiguration vc = ViewConfiguration.get(builder.mRecyclerView.getContext());
mSlop = vc.getScaledTouchSlop();
...
case MotionEvent.ACTION_DOWN: {
pressStartTime = System.currentTimeMillis();
pressedX = motionEvent.getX();
pressedY = motionEvent.getY();
...
case MotionEvent.ACTION_UP: {
long pressDuration = System.currentTimeMillis() - pressStartTime;
if (pressDuration < MAX_CLICK_DURATION && distance(pressedX, pressedY, motionEvent.getX(), motionEvent.getY()) < mSlop) {
mItemClickCallback.onClick(mRecyclerView.getChildPosition(mDownView));
return true;
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
Messager messager = processingEnv.getMessager();
for (Element element : env.getElementsAnnotatedWith(GetMsg.class)) {
PackageElement packageElement = (PackageElement) element
.getEnclosingElement();
//获取该注解所在类的包名
String packageName = packageElement.getQualifiedName().toString();
TypeElement classElement = (TypeElement) element;
//获取该注解所在类的类名
String className = classElement.getSimpleName().toString();
//获取该注解所在类的全类名
String fullClassName = classElement.getQualifiedName().toString();
VariableElement variableElement = (VariableElement) element.getEnclosingElement();
//获取方法名
String methodName = variableElement.getSimpleName().toString();
//获取该注解的值
int id = classElement.getAnnotation(GetMsg.class).id();
String name = classElement.getAnnotation(GetMsg.class).name();
messager.printMessage(Diagnostic.Kind.NOTE,
"Annotation class : packageName = " + packageName);
messager.printMessage(Diagnostic.Kind.NOTE,
"Annotation class : className = " + className);
messager.printMessage(Diagnostic.Kind.NOTE,
"Annotation class : fullClassName = " + fullClassName);
messager.printMessage(Diagnostic.Kind.NOTE,
"Annotation class : methodName = " + methodName);
messager.printMessage(Diagnostic.Kind.NOTE,
"Annotation class : id = " + id + " name = " + name);
}
return true;
}
相关文章
- 下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
- 这篇文章主要给大家介绍了关于C#创建自定义控件及添加自定义属性和事件使用的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-06-25
- 本文实例讲述了JS实现自定义简单网页软键盘效果。分享给大家供大家参考,具体如下:这是一款自定义的简单点的网页软键盘,没有使用任何控件,仅是为了练习JavaScript编写水平,安全性方面没有过多考虑,有顾虑的可以不用,目的是学...2015-11-08
Android开发中findViewById()函数用法与简化
findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20- 如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
- 夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
- 为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
- 如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
- 深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20
- 下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02
- 自定义一个jquery模态窗口插件,将它集成到现有平台框架中时,它只能在mainFrame窗口中显示,无法在顶层窗口显示. 解决这个问题的办法: 通过以下代码就可能实现在顶层窗口弹窗 复制代码 代码如下: $(window.top.documen...2014-05-31
- java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
- TextView默认是横着显示了,今天我们一起来看看Android设置TextView竖着显示如何来实现吧,今天我们就一起来看看操作细节,具体的如下所示。 在开发Android程序的时候,...2016-10-02
- 这篇文章主要介绍了自定义feignClient的常见坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-20
- 今天小编就为大家分享一篇pytorch 自定义卷积核进行卷积操作方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-05-06
android.os.BinderProxy cannot be cast to com解决办法
本文章来给大家介绍关于android.os.BinderProxy cannot be cast to com解决办法,希望此文章对各位有帮助呀。 Android在绑定服务的时候出现java.lang.ClassCastExc...2016-09-20- 这篇文章主要介绍了Android 实现钉钉自动打卡功能的步骤,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下...2021-03-15
- 下面我们来看一篇关于Android 开发之布局细节对比:RTL模式 ,希望这篇文章对各位同学会带来帮助,具体的细节如下介绍。 前言 讲真,好久没写博客了,2016都过了一半了,赶紧...2016-10-02
PHP YII框架开发小技巧之模型(models)中rules自定义验证规则
YII的models中的rules部分是一些表单的验证规则,对于表单验证十分有用,在相应的视图(views)里面添加了表单,在表单被提交之前程序都会自动先来这里面的规则里验证,只有通过对其有效的限制规则后才能被提交,可以很有效地保证...2015-11-24- 这篇文章主要介绍了jquery自定义插件开发之window的实现过程的相关资料,需要的朋友可以参考下...2016-05-09