第一份功能较多的安卓项目--纪念日app
来源:互联网 发布:linux 重启 编辑:程序博客网 时间:2024/05/19 04:52
因为正值跟女朋友在一起的半周年。所以想着做个她需要的app给她用。其实网上同样功能的app很多,但都有广告,而且比较庞大,她的手机又比较老卡,所以就根据她的需求来写,哈哈,算是我的第一个项目经理吧。
首先说一下她的需求:
- 倒数日的功能,能够显示某个日子离现在还有几天,提供自动排序的功能
- 纪念日的功能,能够显示某个日子已经过去了几天,提供两种显示方法,日跟月。
- 手电筒的功能
- 备注功能。即倒数日中能够添加备注(未实现)
接下来就说一下实现的过程:
首先是设计界面,先做好下xml,经验表明,边写功能边敲代码绝对是不对的,因为会很乱。设想有一个登陆界面,界面上是头像,有圆角的输入框(自定义),有圆角的按钮
pw_shape.xml
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" android:padding="10dp"> <!--solid表示填充颜色,如果想让输入框看起来像透明的一样就让color跟背景颜色一样即可--> <solid android:color="#FFFFFF"></solid> <!--corners表示四个角的弧度,注意bottomRightRadius是左下角,left是右下角的弧度--> <corners android:bottomRightRadius="15dp" android:bottomLeftRadius="15dp" android:topLeftRadius="15dp" android:topRightRadius="15dp" /> <!--stroke表示描边,width表示宽度,color为描边的颜色--> <stroke android:width="2dp" android:color="#FF99CC"/> <!--padding:距离边缘的距离--> <padding android:left="10dp"/> </shape>
手电筒在登陆界面。手电筒的代码其实挺简单的。主要就是打开闪光灯。代码如下
lightBtn.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v){ if(!flag){ layout.setBackgroundColor(Color.parseColor("#292421")); lightBtn.setBackgroundResource(R.drawable.flash_head); Camera camera = Camera.open(); parameters = camera.getParameters(); parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);// 开启 camera.setParameters(parameters); camera.startPreview(); flag=true; }else{ flag=false; layout.setBackgroundColor(Color.parseColor("#FFFFFF")); lightBtn.setBackgroundResource(R.drawable.log_in_head_2); parameters.setFlashMode(Parameters.FLASH_MODE_OFF);// 关闭 camera.setParameters(parameters); camera.stopPreview(); camera.release(); camera=null; } } });
开启的逻辑:
Camera camera = Camera.open();//打开CameraParameters parameters = camera.getParameters(); //获得参数 parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);// 将闪光灯的模式设为开启camera.setParameters(parameters);camera.startPreview(); //开启闪关灯
关闭的逻辑:
layout.setBackgroundColor(Color.parseColor("#FFFFFF")); lightBtn.setBackgroundResource(R.drawable.log_in_head_2); parameters.setFlashMode(Parameters.FLASH_MODE_OFF);// 关闭 camera.setParameters(parameters);camera.stopPreview();camera.release();camera=null;//*
这里同上,只需要将parameter设为off,再stopPreview,再release即可。要注意的一点便是:release后要将camera设为null,否则关了再开会报错,提示camera已经被使用
之后便什么新东西,添加Button,EditText等。
然后便是纪念日的设计,同样先设计xml。因为女票要求简单,只需要界面简洁,所以就上方自己设计的普通的菜单,下面是个自定义的listView
自己定制的菜单:
其实就是一层layout。然后在里面放自己需要的东西。那我们一般的都是上面一横条,横条中间是标题,两边是按钮,新建一个LinearLayout。一次放入Button,TextView,Button.
<?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="wrap_content" android:background="@drawable/date" > <Button android:id="@+id/title_btn_back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="返回" android:textColor="#fff"/> <!--要将TextView置中,则要将layout_width置0,layout_weight="1",这样会将一行分为两半,其中TextView占一半,另外两个button各占1/4--> <TextView android:id="@+id/title_text" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight="1" android:gravity="center" android:text="纪念日" android:textColor="#fff" android:textSize="24sp" /><Button android:id="@+id/title_btn_add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="新建" android:textColor="#fff"/></LinearLayout>
这个xml有两点要注意的,就是android:layout_gravity跟android:gravity的区别。
android:gravity是文字在控件中的对齐方式,而android:layout_gravity是控件在layout中的对齐方式。因为我们这个layout的高度设为wrap_content了,所以就只有按钮的高度。之后这个xml就可以被其他引用了。只需要将其他layout的标题栏隐藏,然后在xml中引入即可。隐藏标题栏的代码:
super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);//这一句一定要在setContentView前setContentView(R.layout.activity_count_down);
然后便是listview的设计。因为我是想着左边一个纪念日的内容,然后右边一个框里面有天数,框的左边有”已经“二字,所以定制list_item.xml
首先将layout的orientation设为”horizontal”
然后将显示内容的TextView设为android:layout_weight=”1”。这样显示出来的效果就是“已经”二字贴着右边的框。
然后右边的框因为系统没有所以我们需要自己定制,其实也简单,就是一层有背景的layout,然后里面有一个TextView,设置其layout_gravity为center将其放在中间就可以了。
接着便是添加逻辑,主要是点击所在行可以进行编辑,长按弹出菜单可以删除,摇一摇可以让框3D旋转。
Adapter的重写,需要注意要把框所在的layout也申请个空间,因为字体是在这层layout上更改的。
class ViewHolder { private LinearLayout countDownLayout; private TextView content; private TextView date; } private DayAdapter(Context context, ArrayList<Day1> dates) { this.context = context; this.dates = dates; } @Override public int getCount() { // TODO Auto-generated method stub return dates.size(); } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return dates.get(arg0); } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return arg0; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ViewHolder vh; View view; if (convertView == null) { vh = new ViewHolder(); /** *注意这里要先inflate自定义的list_item */ view = LayoutInflater.from(context).inflate(R.layout.list_item, null); /** *注意这里要给layout一个空间 */ vh.countDownLayout = (LinearLayout) view.findViewById(R.id.count_down_layout); vh.content = (TextView) view.findViewById(R.id.count_down_content); vh.date = (TextView) view.findViewById(R.id.count_down_datetext); view.setTag(vh); } else { view = convertView; vh = (ViewHolder) view.getTag(); } vh.content.setText(dates.get(position).content); int passed = dates.get(position).days; if (first){ vh.date.setText(passed + "天"); first=false; } else { if (mark == 1) { applyRotation(vh.countDownLayout, 0, 90); vh.date.setText(passed + "天"); } else { applyRotation(vh.countDownLayout, 0, 90); vh.date.setText(passed + "月"); } } return view; } }
3D翻转特效:这个不懂,网上找的代码,需要翻转时调用applyRotation(layout,start,end)即可。一般把start设为0,end设为90,因为我们要翻转的是整个框,所以layout传入countDownLayout。因为我这个dayadapter中的list的泛型是Day1,其中有int型的一个数字,就是显示出来的天数。这样设计是为了能够让摇一摇时getView得以被调用(list中内容有变化,使用notifyDataSetChanged()才有效。)
private void applyRotation(LinearLayout layout, float start, float end) { final float centerX = layout.getWidth() / 2.0f; final float centerY = layout.getHeight() / 2.0f; final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end, centerX, centerY, 310.f, true); rotation.setDuration(500); rotation.setFillAfter(true); rotation.setInterpolator(new AccelerateInterpolator()); rotation.setAnimationListener(new DisplayNextView(layout)); layout.startAnimation(rotation);}private final class DisplayNextView implements Animation.AnimationListener { private LinearLayout layout; DisplayNextView(LinearLayout layout) { this.layout = layout; } public void onAnimationStart(Animation animation) { } public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation arg0) { // TODO Auto-generated method stub layout.post(new SnapViews(layout)); } } private final class SnapViews implements Runnable { private LinearLayout layout; SnapViews(LinearLayout layout) { this.layout = layout; } public void run() { final float centerX = layout.getWidth() / 2.0f; final float centerY = layout.getHeight() / 2.0f; Rotate3dAnimation rotation = null; layout.requestFocus(); rotation = new Rotate3dAnimation(90, 0, centerX, centerY, 310.0f, false); rotation.setDuration(500); rotation.setInterpolator(new DecelerateInterpolator()); layout.startAnimation(rotation); } }}
之后是摇一摇。就是微信摇一摇的原理。使用手机的加速度传感器来感应是否有摇动。
private SensorManager sensorManager;sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);Sensor sensor =sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);sensorManager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_NORMAL);/** *在onSensorChanged中添加代码逻辑,我设置两次摇一摇的时间不能超过4秒 */private SensorEventListener listener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { float x = Math.abs(event.values[0]); float y = Math.abs(event.values[1]); float z = Math.abs(event.values[2]); if ((System.currentTimeMillis() - CountDownActivity.currentTime > 4000) && (x > 12 || y > 12 || z > 12)) { CountDownActivity.currentTime = System.currentTimeMillis(); if (mark == 1) { mark = 2; for (Day1 d : dayLists) { d.days = countDay(d.date, mark); adapter.notifyDataSetChanged(); } } else if (mark == 2) { mark = 1; for (Day1 d : dayLists) { d.days = countDay(d.date, mark); } adapter.notifyDataSetChanged(); } } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } };
弹出菜单:首先给菜单注册,然后重写代码即可。add方法的四个参数含义:
menu.add(groupId, itemId, order, title)
groupld 这个菜单的组别
itemid 是用来获取这个指定菜单项的.可以定义常量,不容易混,比如final int DELETE=1;
所谓order就是这个组别的第几项,0为第一项
title 不用说都知道是显示的标题了
registerForContextMenu(list);@Overridepublic void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { menu.add(0, 1, 0, "删除");}@Override public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()) { case 1: Day1 d = (Day1) adapter.getItem(clickId); Log.e("clickId", " " + clickId); String content = d.content; for (Day1 d1 : dayLists) { if (d1.content.equals(content)) { dayLists.remove(d1); break; } } SQLiteDatabase db = dbHelper.getWritableDatabase(); db.delete("CountDays", "content=?", new String[] { d.content }); adapter.notifyDataSetChanged(); } return true; }
至于添加详情的代码则没什么好写的了。界面也没有设计。
- 第一份功能较多的安卓项目--纪念日app
- 功能较多的记事本
- 安卓app自动更新功能
- 安卓开发--构建你的第一个APP
- 鲤鱼日语:第一个自己的安卓APP
- 安卓怎么实现计算纪念日
- 安卓的第一份实验单【2014年10月15日布置,11月11日上交】
- 给你的安卓app添加下拉刷新功能吧!
- 如何利用跑app较快的第三方模拟器连接eclipse,来运行安卓程序。
- Blog的第一份log
- 我的第一份工作
- 我的第一份工作
- 我的第一份文档
- 我的第一份工作
- 我的第一份blog
- 我的第一份兼职
- 我的第一份工
- 我的第一份offer
- 2016年全面前端面试题
- Android开发之高亮引导
- 初识asp.net
- 87-----hibernate的几种映射关系总结
- POJ-2195 Going Home(最小费用最大流)
- 第一份功能较多的安卓项目--纪念日app
- AFNetworking 3.0封装post请求body里面内容是空的
- 勾股定理一日一证连载10
- C# HTMLHelper类对Html源码处理教程与源码下载
- oracle11g在Server08R2服务器上安装部署常见问题
- Net操作配置文件(Web.config|App.config)通用类
- LeetCode 053 Maximum Subarray
- 一个最基本的CSS文件处理
- 高效快速的项目开发