引语: 我是个程序猿,一天我坐在路边一边喝水一边苦苦检查bug。
这时一个乞丐在我边上坐下了,开始要饭,我觉得可怜,就给了他1块钱。 然后接着调试程序。他可能生意不好,就无聊的看看我在干什么,然后过了一会,他缓缓地指着我的屏幕说,这里少了个分号…

谁说咱们程序猿不能写出既幽默又能懂的博客呢,本人想推出一系列博文,可以给刚接触Android开发的做一个参考,也可以与接触Android已久的各路大神比较一下,本人喜欢交流,如果有写得不好的地方,欢迎大家指出.如果有更好的效果或者功能,希望大家多多指点,互相学习可以共同进步.

说了这么多,现在进入今天的猪蹄,推出<<暴走漫画系列--高仿淘宝收货地址>>,有网购经验的同学应该对这个很熟悉,在淘宝的Android客户端里面,有一个功能是设置收货地址,不清楚的同学可以自己下载个淘宝客户端,自己添加一下看看.

本人一向喜欢贴图,这样有图有真相,才能说服每个人,废话不多说先上自己程序启动画面,然后运行界面,最后一张是淘宝客户端对照图.

 图片震楼  启动界面 运行界面 淘宝界面

淘宝客户端无法录屏所以这里只能上静态的,大家可以自己打开淘宝客户端看看.

下面进行详细的代码讲解:

(一)本人在程序启动的时候开了一条后台服务landDivideServeice,目的是为了将全国的省市县总共4,189条数据插入到手机数据库里面去,原本的数据是保存在7个txt里面的,由于放在txt里面,读取操作很不方便,所以我把它放到数据库,在后面的地区筛选很快就出来,这个比淘宝还快哦,不信你们可以试一下.

这里要注意的一点是landDivideServeice是继承IntentService的,不是直接继承Service的.

IntentService是继承于Service并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统Service一样,同时,当任务执行完后,IntentService会自动停止,而不需要我们去手动控制。

简单的说IntentService类似于一条后台线程,但操作完成时,我们不用手动去关闭Serveice,他会自动关闭.MyIntentService继承IntentService,之后必须实现一个无参数的构造方法MyIntentService(),然后还要重写onHandleIntent(Intent
intent);此后所有的后台操作即可在onHandleIntent(Intent intent)执行;

public class MyIntentService extends IntentService {

	//必须实现的
public MyIntentService() {
super("MyIntentService");
// TODO Auto-generated constructor stub
} @Override
protected void onHandleIntent(Intent arg0) {
// TODO Auto-generated method stub
//具体的操作
} }

 so
ga...

IntentService详细解析:

http://blog.csdn.net/ryantang03/article/details/8146154

http://blog.csdn.net/flowingflying/article/details/7616333

(二)在程序启动的第一个activity里,我弄了一条倒计时线程,时间总共是20秒,目的是想为数据写入数据库争取多一些时间,如果你进入地址筛选界面,看到数据不全或者报错,是因为数据还没有写完.

实现倒计时功能主要是继承CountDownTimer类,重写onTick和onFinsh这两个方法,onFinish()中的代码是计时器结束的时候要做的事情;onTick(Long m)中的代码是你倒计时开始时要做的事情,构造方法TimeCount()中的两个参数中,前者是倒计的时间数,后者是倒计每秒中间
的间隔时间,都是以毫秒为单位.例如要倒计时30秒,每秒中间间隔时间是1秒,两个参数可以这样写TimeCount(20000,1000).

TimeCount time = new TimeCount(20000, 1000);
time.start();
/* 定义一个倒计时的内部类 */
class TimeCount extends CountDownTimer {
public TimeCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
} @Override
public void onFinish() { //倒计时执行结束时操作
next = 0;
} @Override
public void onTick(long millisUntilFinished) { //倒计执行时操作
}
}

(三)剩下的主要是一些界面的切换跟数据的读取,只要思路正确是不会被搞混的.

landDivideDB = LandDivideDB.getInstance(getBaseContext());
List<LandDivide> landDivide = landDivideDB.queryAddress("superior=?", new String[]{"1"});
Iterator<LandDivide> iterator = null;
if(landDivide!=null){
iterator = landDivide.iterator(); while(iterator.hasNext()){
LandDivide l = iterator.next();
sheng.add(l.getName());
}
}else{
return;
}
mListView1.setOnItemClickListener(new OnItemClickListener() {

			@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
// TODO Auto-generated method stub
mLinearLayout1.setVisibility(View.GONE);
mLinearLayout2.setVisibility(View.VISIBLE);
mLinearLayout3.setVisibility(View.GONE); shi.clear();
String name = sheng.get(position);
String code = null;
shengStr = name;
shengTxt2.setText(name); List<LandDivide> landDivide = landDivideDB.queryAddress("name=?", new String[]{name});
Iterator<LandDivide> iterator= landDivide.iterator();
while(iterator.hasNext()){
LandDivide l = iterator.next();
code = l.getCode();
break;
} List<LandDivide> landDivide_2 = landDivideDB.queryAddress("superior=?", new String[]{code});
Iterator<LandDivide> iterator_2= landDivide_2.iterator();
while(iterator_2.hasNext()){
LandDivide l = iterator_2.next();
shi.add(l.getName());
} shiAdapter.notifyDataSetChanged();
quAdapter.clear();
quAdapter.notifyDataSetChanged();
}
}); mListView2.setOnItemClickListener(new OnItemClickListener() { @Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
// TODO Auto-generated method stub qu.clear(); String name = shi.get(position);
String code = null; shiStr = name;
shengTxt3.setText(shengStr);
shiTxt3.setText(name); List<LandDivide> landDivide = landDivideDB.queryAddress("name=?", new String[]{name}); Iterator<LandDivide> iterator= landDivide.iterator();
while(iterator.hasNext()){
LandDivide l = iterator.next();
code = l.getCode();
break;
} List<LandDivide> landDivide_2 = landDivideDB.queryAddress("superior=?", new String[]{code});
if(landDivide_2!=null){
Iterator<LandDivide> iterator_2= landDivide_2.iterator();
while(iterator_2.hasNext()){
LandDivide l = iterator_2.next();
qu.add(l.getName());
}
} quAdapter.notifyDataSetChanged(); if(qu.size()<1){
mLinearLayout1.setVisibility(View.GONE);
mLinearLayout2.setVisibility(View.VISIBLE);
mLinearLayout3.setVisibility(View.GONE); Intent i = new Intent(AddressChoose.this,BuyAddress.class);
i.putExtra("address", shengStr+","+shiStr);
startActivity(i);
finish(); }else{ mLinearLayout1.setVisibility(View.GONE);
mLinearLayout2.setVisibility(View.GONE);
mLinearLayout3.setVisibility(View.VISIBLE); mListView3.setVisibility(View.VISIBLE);
topView3.setText("请选择 县区/其他...");
}
}
}); mListView3.setOnItemClickListener(new OnItemClickListener() { @Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
// TODO Auto-generated method stub String name = qu.get(position); quStr = name; Intent i2 = new Intent(AddressChoose.this,BuyAddress.class);
i2.putExtra("address", shengStr+" "+shiStr+" "+quStr);
startActivity(i2);
finish();
}
});

(四)这个是选择好地址之后的界面,主要还是界面的转换跟焦点的获取

有时候setFocusable(true)跟setFocusableInTouchMode(true)并不能使控件获得焦点,要再之前加上一句requestFocus(),这样控件就可以获得焦点.

OnFocusChangeListener focusChanger = new OnFocusChangeListener() {

		@Override
public void onFocusChange(View v, boolean hasFocus) {
// TODO Auto-generated method stub
myAddress.setStreet(jiequText.getText().toString());
myAddress.setName(nameText.getText().toString());
myAddress.setPhone(phoneText.getText().toString()); switch (v.getId()) {
case R.id.my_set_buyaddress_jiequ:
if (!hasFocus && myAddress.getStreet().length() > 0) {
jiequText.setVisibility(View.GONE);
jiequLinear.setVisibility(View.VISIBLE); jiequTextView.setText(myAddress.getStreet());
} if (hasFocus) {
jiequText.setSelectAllOnFocus(true);
}
break;
case R.id.my_set_buyaddress_name:
if (!hasFocus && myAddress.getName().length() > 0) {
nameText.setVisibility(View.GONE);
nameLinear.setVisibility(View.VISIBLE); nameTextView.setText(myAddress.getName());
} if (hasFocus) {
nameText.setSelectAllOnFocus(true);
}
break;
case R.id.my_set_buyaddress_phone:
if (!hasFocus && myAddress.getPhone().length() > 0) {
phoneText.setVisibility(View.GONE);
phoneLinear.setVisibility(View.VISIBLE); phoneTextView.setText(myAddress.getPhone());
}
if (hasFocus) {
phoneText.setSelectAllOnFocus(true);
}
break; default:
break;
}
}
}; OnClickListener click = new OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.my_set_buyaddress_sheng_linear:
Intent i = new Intent(BuyAddress.this, AddressChoose.class);
i.putExtra("Boolean", "aaa");
startActivity(i);
break;
case R.id.my_set_buyaddress_jiequ_linear:
jiequText.setVisibility(View.VISIBLE);
jiequLinear.setVisibility(View.GONE); jiequText.setFocusable(true);
jiequText.setFocusableInTouchMode(true); jiequText.requestFocus();
break;
case R.id.my_set_buyaddress_name_linear:
nameText.setVisibility(View.VISIBLE);
nameLinear.setVisibility(View.GONE); nameText.setFocusable(true);
nameText.setFocusableInTouchMode(true); nameText.requestFocus();
break;
case R.id.my_set_buyaddress_phone_linear:
phoneText.setVisibility(View.VISIBLE);
phoneLinear.setVisibility(View.GONE); phoneText.setFocusable(true);
phoneText.setFocusableInTouchMode(true); phoneText.requestFocus();
break;
case R.id.my_set_buyaddress_address_btn:
myAddress.setStreet(jiequText.getText().toString());
myAddress.setName(nameText.getText().toString());
myAddress.setPhone(phoneText.getText().toString()); if (myAddress.getPhone().length() > 0) {
phoneText.setVisibility(View.GONE);
phoneLinear.setVisibility(View.VISIBLE);
phoneTextView.setText(myAddress.getPhone());
}
postBtn.requestFocus(); postBtn.setFocusable(true);
postBtn.setFocusableInTouchMode(true); if (myAddress.getProvinces().length() < 1 || myAddress.getStreet().length() < 1
|| myAddress.getName().length() < 1 || myAddress.getPhone().length() < 1) {
Toast.makeText(getBaseContext(), "请完整填写收货人资料", 0).show();
return;
} myAddress.setStatus(checkBox.isChecked());
AddressDB addressDB = AddressDB.getInstance(getBaseContext()); if(checkBox.isChecked()){
List<AddressInfo> list = addressDB.queryAddress();
if(list!=null){
Iterator<AddressInfo> iterator = list.iterator();
while(iterator.hasNext()){
AddressInfo a = iterator.next();
a.setStatus(false);
addressDB.updeteAddress(a);
}
} } if (addressinfo != null) {
if(addressDB.updeteAddress(myAddress)){
Toast.makeText(getBaseContext(), "修改收货地址成功", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(getBaseContext(), "修改收货地址失败", Toast.LENGTH_LONG).show();
}
} else { SimpleDateFormat format = new SimpleDateFormat(
"yyyyMMddHHmmss");
Date date = new Date();
String id = format.format(date);
myAddress.setId(id); if(addressDB.insertAddress(myAddress)){
Toast.makeText(getBaseContext(), "添加收货地址成功", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(getBaseContext(), "添加收货地址失败", Toast.LENGTH_LONG).show();
}
} Intent intent = new Intent(BuyAddress.this, PersonAddress.class);
startActivity(intent);
finish(); break; case R.id.download_layout1:
finish();
break;
default:
break;
}
}
};

更多的代码解析,大家可以下载我的demo,看一下哦

最后就这样了哈,有什么不懂的或者更好的建议的,可以提出来哈,欢迎大家指教

小弟不才,参加了CSDN的博客大赛,在这里想请各位帮个忙,投下您尊贵的一票,您说都看到这里了,是不是,底下就是投票的位置了,就顺便投一下嘛(如果底下没有投一票的按钮,请点击下面的链接,进入投票页面,拉到页面底下即可投票).

投票地址:http://vote.blog.csdn.net/Article/Details?articleid=32936187

源码地址: http://download.csdn.net/detail/chillax_li/7531409

尊重原创,转载请注明出处:http://blog.csdn.net/chillax_li/article/details/32936187

暴走漫画系列之高仿淘宝收货地址(附demo)的更多相关文章

  1. 高仿淘宝送货地址暴走漫画系列(附demo)

    演讲: 我是个程序员,一天我坐在路边一边喝水一边苦苦检查bug. 这时一个乞丐在我边上坐下了,開始要饭,我认为可怜.就给了他1块钱. 然后接着调试程序.他可能生意不好,就无聊的看看我在干什么.然后过了 ...

  2. 【地图API】地址录入时如何获得准确的经纬度?淘宝收货地址详解

    用户需求:管理者需要录入一批商户,并在地图上把商户展示出来.但发现一些商户的地址描述并不清楚,导致商户位置出错.如何获得更加准确的商户位置呢? 分析:假设地址准确的,可以通过地址解析,得到准确的经纬度 ...

  3. 高仿淘宝和聚美优品商城详情页实现《IT蓝豹》

    高仿淘宝和聚美优品商城详情页实现 android-vertical-slide-view高仿淘宝和聚美优品商城详情页实现,在商品详情页,向上拖动时,可以加载下一页. 使用ViewDragHelper, ...

  4. android版高仿淘宝客户端源码V2.3

    android版高仿淘宝客户端源码V2.3,这个版本我已经更新到2.3了,源码也上传到源码天堂那里了,大家可以看一下吧,该应用实现了我们常用的购物功能了,也就是在手机上进行网购的流程的,如查看产品(浏 ...

  5. (转)Android 仿订单出票效果 (附DEMO)

    之前我下载了BaseAnimation 开源库(BaseAnimation是基于开源的APP,致力于收集各种动画效果) BaseAnimation 转载的链接:http://blog.csdn.net ...

  6. 高仿QQ即时聊天软件开发系列之三登录窗口用户选择下拉框

    上一篇高仿QQ即时聊天软件开发系列之二登录窗口界面写了一个大概的布局和原理 这一篇详细说下拉框的实现原理 先上最终效果图 一开始其实只是想给下拉框加一个placeholder效果,让下拉框在未选择未输 ...

  7. 高仿QQ即时聊天软件开发系列之二登录窗口界面

    继上一篇高仿QQ即时聊天软件开发系列之一开端之后,开始做登录窗口 废话不多说,先看效果,只有界面 可能还有一些细节地方没有做,例如那个LOGO嘛,不要在意这些细节 GIF虽短,可是这做起来真难,好吧因 ...

  8. (android高仿系列)今日头条 --新闻阅读器 (三) 完结 、总结 篇

    从写第一篇今日头条高仿系列开始,到现在已经过去了1个多月了,其实大体都做好了,就是迟迟没有放出来,因为我觉得,做这个东西也是有个过程的,我想把这个模仿中一步一步学习的过程,按照自己的思路写下来,在根据 ...

  9. (android高仿系列)今日头条 --新闻阅读器 (二)

    高仿今日头条 --- 第一篇:(android高仿系列)今日头条 --新闻阅读器 (一)    上次,已经完毕了头部新闻分类栏目的拖动效果. 这篇文章是继续去完好APP 今日头条  这个新闻阅读器的其 ...

  10. 浅谈android中只使用一个TextView实现高仿京东,淘宝各种倒计时

    今天给大家带来的是只使用一个TextView实现一个高仿京东.淘宝.唯品会等各种电商APP的活动倒计时.近期公司一直加班也没来得及时间去整理,今天难得歇息想把这个分享给大家.只求共同学习,以及自己兴许 ...

随机推荐

  1. 以“升舱”之名,谈谈云原生数据仓库AnalyticDB的核心技术

    简介: 企业级云原生数据仓库AnalyticDB提出了升舱计划,旨在承担和帮助金融.运营商.政务等行业构建下一代数据管理和分析系统,以应对不断增长的数据规模,业务数字化转型,和传统数仓替换升级需求.7 ...

  2. [GPT] ./ssh/known_hosts 是什么

      ~/.ssh/known_hosts 是一个SSH客户端用来存储已知的远程主机的公钥的文件,这些公钥用于验证连接到远程主机时它们是否为真实可信的主机. 当你首次通过SSH连接到一个新的远程主机时, ...

  3. [GPT] 神经网络模型方面的课程、神经网络模型与深度学习

      现在有很多关于神经网络模型的课程.以下是一些比较受欢迎的神经网络模型课程: Stanford CS231n:卷积神经网络(CNNs)课程 Deep Learning Specialization: ...

  4. [FAQ] Fontconfig error: Cannot load default config file

      在使用一些第三方库时(比如生成图片),如果出现此提示,说明系统里缺少字体. 在 Ubuntu 上可以运行:$ apt-get install fontconfig 在 Centos 上可以运行:$ ...

  5. [TP5] 浅谈 ThinkPHP 的 Hook 行为事件及监听执行

    TP5 中使用 \think\Hook::add('xx', '\app\xxx\behavior\Xx') 注册行为. 也可以在 application/tags.php 中统一注册. 在需要监听执 ...

  6. [ST] 音悦Tai 凉了,一段印记成为过去时

    互联网上依旧流传着音悦台的传说,过去十年间,你我也许都曾是音悦台的用户. 很多MV的右上角依然是 YinYueTai 的 Logo,比如 Siren-宣美,算是一个时代的印记吧. 互联网企业,即便是真 ...

  7. OpenTK 入门 初始化窗口

    本文属于 OpenTK 入门博客,这是一项使用 C# 做底层调用 OpenGL 和 OpenAL 和 OpenCL 的技术.但值得一提的是,如果是想做渲染相关的话,当前是不建议使用 OpenGL 的, ...

  8. WPF 在 .NET Core 3.1.19 版本 触摸笔迹偏移问题

    在更新到 .NET 6 发布之前的,在 2021.11.02 的 .NET Core 版本,都会存在此问题.在 WPF 应用里面,如果在高 DPI 下,进行触摸书写,此时的笔迹将会偏移.核心原因是在这 ...

  9. dotnet OpenXML 文本删除线解析方法

    本文来告诉大家如何解析读取在 OpenXML 里面存放的文本删除线,本文使用 PowerPoint 作为例子来告诉大家如何读取然后在 WPF 应用里面显示 在开始之前,期望大家已了解如何在 dotne ...

  10. UWP 写入图片 Exif 信息

    本文告诉大家如何在 UWP 中,保存图片的时候,写入 Exif 信息,也就是如照片的 相机型号 制造商 光圈值等信息的写入 在 UWP 中,保存图片或照片需要用到图片编码器,在使用编码器写入前可以设置 ...