diff --git a/.idea/.name b/.idea/.name
deleted file mode 100644
index b1efdd1..0000000
--- a/.idea/.name
+++ /dev/null
@@ -1 +0,0 @@
-DavidAndroidProjectTools
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
deleted file mode 100644
index 96cc43e..0000000
--- a/.idea/compiler.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
deleted file mode 100644
index e7bedf3..0000000
--- a/.idea/copyright/profiles_settings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/.idea/dictionaries/Android.xml b/.idea/dictionaries/Android.xml
deleted file mode 100644
index 4f91d68..0000000
--- a/.idea/dictionaries/Android.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
deleted file mode 100644
index 97626ba..0000000
--- a/.idea/encodings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
deleted file mode 100644
index 78a2fa3..0000000
--- a/.idea/gradle.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index df20ccd..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 51e88d1..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
deleted file mode 100644
index 7f68460..0000000
--- a/.idea/runConfigurations.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 94a25f7..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..e69de29
diff --git a/README.md b/README.md
index dbd66dd..0cc362b 100644
--- a/README.md
+++ b/README.md
@@ -4,27 +4,7 @@ Android开发常用功能大集合。以及知识点的详解代码
项目名称:【Android利器】
-前提说明,仅供参考.勿用于商业.有些接口是我自己抓取的,版权归原公司所有.
-
-作者:[程序员小冰](http://blog.csdn.net/qq_21376985)
-
-[欢迎点击关注我的微博](http://weibo.com/mcxiaobing)
-
-先来看一下这个项目的总体功能图吧(这只是一小部分,会一直更新维护增加功能):
-
-
-
-更过功能欢迎下载APK进行体验(两种方式,建议第二种微云。腾讯Bugly可能有部分手机不兼容问题):
-
-当然除了这两种,你也可以去百度手机助手,91,安卓市场进行下载体验。
-
-1;[点击从腾讯Bugly下载APK进行体验效果](https://beta.bugly.qq.com/davidandroidprojecttools)
-
-
-
-2;[点击从腾讯微云下载APK进行体验效果](https://sz-btfs-v2-yun-ftn.weiyun.com/ftn_handler/89277a84dd3265346828c6d955f0fad42dd67c19e3710c75024ee42d5ee317c075904f90706d63288339b2b52e82a6ceeab7dd1ab03e87831d6e47ed2920fb20/Android.apk?fname=Android.apk&from=30111&version=2.0.0.2&uin=986945193)
-
-
+前提说明,仅供参考.若是用于商业本人不负任何法律责任.有些接口是我自己抓取的,版权归原公司所有.
此项目是小冰工作中总结常用的功能大集合,防止以后用到的话重复造轮子,而且还有常用控件
@@ -38,7 +18,7 @@ Android开发常用功能大集合。以及知识点的详解代码
当然,如果你有更好的功能,欢迎联系我。好知识一起共享。Thank You!下面是部分的功能知识点介绍:
-包名架构图(目前,还在更戏中......)
+包名图(当然,这个项目功能点挺多的,具体请下载apk或者运行项目自己看。喜欢的朋友可以点star)

@@ -54,7 +34,7 @@ a,二维码的扫描与生成功能 b,圆形头像的功能
4,著名的一些开源框架的使用以及封装
-【JAVA方面】java知识点:
+【JAVA方面,懒得写了,具体自己看吧。反正挺多的知识点。】java知识点:
1,设计模式:单例的恶汉式和懒汉式写法。
@@ -88,10 +68,46 @@ Gson, Xutils2.6, Picasso,Universional_Imageloader, glide,OkHttp,fresco,shareSDK
由于有些功能效果无法展示,具体实现请看项目源代码。
-项目为小冰所写,仅供参考,请勿用于任何商业。转载请说明出处。
+项目为小冰所写,仅供参考,转载应用本人将不负责任何法律。转载请说明出处。
可以直接放在AndroidStudio开发工具中运行,
涉及到第三方服务API以及SDK,记得将Constants类中的API秘钥改为自己的即可。
+更过功能欢迎下载APK进行体验(腾讯Bugly可能有部分手机不兼容问题):
+
+当然除了这种,你也可以去百度手机助手,91,安卓市场进行下载体验。
+
+1;[点击从百度手机助手下载APK进行体验效果](http://shouji.baidu.com/software/11535756.html)
+
+2;[点击从安卓市场下载APK进行体验效果](http://apk.hiapk.com/appinfo/davidandroidprojecttools.qq986945193.com.davidandroidprojecttools/2)
+
+3;[点击从91助手下载APK进行体验效果](http://apk.91.com/Soft/Android/davidandroidprojecttools.qq986945193.com.davidandroidprojecttools-2.html)
+
+4;[点击从腾讯Bugly下载APK进行体验效果](https://beta.bugly.qq.com/davidandroidprojecttools)
+
+
+
+
+部分资源来自互联网收集,并修改,归原作者所有,感谢。
+
+当然如果您感觉我侵犯了您的权益,请私信,我会立刻删除相关内容。
+
+作者:[程序员小冰](http://blog.csdn.net/qq_21376985)
+
+[欢迎点击关注我的微博](http://weibo.com/mcxiaobing)
+
+先来看一下这个项目的总体功能图吧(这只是一小部分,会一直更新维护增加功能):
+
+
+
+
+
+
+
欢迎star,fork,提出更好的建议。版权所有:程序员小冰
+
+当然如果我的项目帮到了你,欢迎进行打赏,请作者喝杯茶。谢谢支持。
+
+
+
diff --git a/app/build.gradle b/app/build.gradle
index 3f20e36..147ce09 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -9,8 +9,8 @@ android {
applicationId "davidandroidprojecttools.qq986945193.com.davidandroidprojecttools"
minSdkVersion 15
targetSdkVersion 23
- versionCode 1
- versionName "1.0"
+ versionCode 2
+ versionName "1.1"
// dex突破65535的限制
multiDexEnabled true
@@ -31,7 +31,9 @@ android {
/*在签名过程中所需要的密钥*/
keyPassword '123456'
//根据自己电脑上的签名秘钥配置 keystore证书在磁盘中的位置
- storeFile file('D:/DavidAndroidProjectTools.jks')
+ //storeFile file('D:/DavidAndroidProjectTools.jks')
+ storeFile file('/Users/david/workspace/androidStudioWorkspace/DavidAndroidProjectTools/app/src/main/DavidAndroidProjectTools.jks')
+
// storeFile file('H:\\StudioWork\\DavidAndroidProjectTools\\app\\src\\main\\DavidAndroidProjectTools.jks')
/*keystore证书的密码*/
storePassword '123456'
@@ -156,8 +158,8 @@ dependencies {
compile 'com.squareup.okhttp3:okhttp:3.4.1'
//fresco的引入
compile 'com.facebook.fresco:fresco:0.13.0'
- /*引入multidex库文件*/
- compile 'com.android.support:multidex:1.0.0'
+ /*引入multidex库文件1.0.0会出现警告信息,1.0.1不回出现第三方jar警告信息*/
+ compile 'com.android.support:multidex:1.0.1'
/*增加注解的使用 butterknife*/
compile 'com.jakewharton:butterknife:8.1.0'
apt 'com.jakewharton:butterknife-compiler:8.1.0'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f690b03..a80b203 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/ListViewIntroduceActivity.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/ListViewIntroduceActivity.java
index 309da2d..bf38cdb 100644
--- a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/ListViewIntroduceActivity.java
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/ListViewIntroduceActivity.java
@@ -31,12 +31,11 @@
/**
* ListView详解的类
- *
+ *
* 注明:当长点击和短点吉事件冲突的话解决方法
- *
+ *
* 1,长按事件的return false改为true就不会监听onclick了
* 2,设置变量(此方法没有尝试)
- *
*/
public class ListViewIntroduceActivity extends BaseActivity {
private ListView mListView;
@@ -52,12 +51,12 @@ protected void initView() {
/**
* 设置ListView中Item的点击事件
*/
- mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ /* mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
ToastUtils.show(mContext, "点击了第" + position + "个", Toast.LENGTH_SHORT);
}
- });
+ });*/
/**
* 监听ListView的滚动事件
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/LocalJsonUpdateAppActivity.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/LocalJsonUpdateAppActivity.java
index 61cc35d..9fa0886 100644
--- a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/LocalJsonUpdateAppActivity.java
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/LocalJsonUpdateAppActivity.java
@@ -6,21 +6,113 @@
* @OsChina空间: https://my.oschina.net/mcxiaobing
*/
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.view.View;
+import android.widget.Button;
+
+import com.nostra13.universalimageloader.utils.L;
+
import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.R;
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.bean.UpdateAppBean;
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.callback.OkHttpBaseCallback;
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.callback.OkHttpStopCallback;
import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.constant.Constants;
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.services.UpdateVersionDownloadService;
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.utils.AppUtils;
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.utils.LogUtil;
+import okhttp3.Response;
+
+import static com.tencent.bugly.beta.Beta.appVersionCode;
+import static davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.constant.Urls.CHECK_UPDATE_APP;
/**
* 调用本地的json数据进行更新apk
*/
-public class LocalJsonUpdateAppActivity extends BaseActivity{
+public class LocalJsonUpdateAppActivity extends BaseActivity {
+ private Button btn_check_update_apk;
+
+ // CHECK_UPDATE_APP
@Override
protected void initView() {
setContentView(R.layout.activity_local_json_update_app);
}
+ private String descripton = "";
+ private String downloadurl = "";
+ private int versionCode = 0;
+
@Override
protected void initData() {
+ btn_check_update_apk = (Button) findViewById(R.id.btn_check_update_apk);
+
+ btn_check_update_apk.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ okHttpUtils.get(CHECK_UPDATE_APP, null, new OkHttpStopCallback() {
+ @Override
+ public void onSuccess(Response response, UpdateAppBean mUpdateAppBean) {
+ if (mUpdateAppBean != null) {
+ if (mUpdateAppBean.getMsg()!=null){
+ descripton = mUpdateAppBean.getMsg().get(0).getDescription();
+ downloadurl = mUpdateAppBean.getMsg().get(0).getDownloadApkUrl();
+ LogUtil.e("codel:"+mUpdateAppBean.getMsg().get(0).getVersionCode());
+ LogUtil.e("descripton:"+mUpdateAppBean.getMsg().get(0).getVersionCode());
+ LogUtil.e("downloadurl:"+mUpdateAppBean.getMsg().get(0).getVersionCode());
+ versionCode = Integer.parseInt(mUpdateAppBean.getMsg().get(0).getVersionCode());
+ LogUtil.e(" AppUtils.getVersionCode(LocalJsonUpdateAppActivity.this)" + AppUtils.getVersionCode(LocalJsonUpdateAppActivity.this));
+ if (versionCode> AppUtils.getVersionCode(LocalJsonUpdateAppActivity.this)) {
+ //如果服务端code大于本地,则说明有更新。
+ showUpdateDailog();
+ }
+ }
+ }
+
+ }
+ });
+ }
+ });
+
+ }
+
+
+ /**
+ * 升级更新 弹出对话框
+ */
+ private void showUpdateDailog() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ //这里最新版本和描述均为后台接口URL传来的
+ builder.setTitle("更新最新版本:" + AppUtils.getVersionName(this));
+ builder.setMessage(descripton);
+// builder.setCancelable(false);//禁止用户点击返回按钮 (尽量不要用)
+ builder.setPositiveButton("立即更新", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ Intent intent = new Intent(mContext, UpdateVersionDownloadService.class);
+ intent.putExtra("url", downloadurl);
+ mContext.startService(intent);
+ }
+ });
+ builder.setNegativeButton("以后再说", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+
+ }
+ });
+ //设置用户取消的监听,用户点击返回键是会触发
+ builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
+
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ dialog.dismiss();
+ }
+ });
+ builder.show();
}
@Override
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/ProgressWebViewActivity.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/ProgressWebViewActivity.java
index a29733b..26c4859 100644
--- a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/ProgressWebViewActivity.java
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/ProgressWebViewActivity.java
@@ -2,6 +2,7 @@
import android.content.Intent;
import android.net.Uri;
+import android.util.Log;
import android.webkit.DownloadListener;
import android.webkit.URLUtil;
import android.webkit.WebSettings;
@@ -13,6 +14,8 @@
import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.utils.URLUtils;
import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.view.ProgressWebView;
+import static davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.R.id.webview;
+
/**
* @author :程序员小冰
* @新浪微博 :http://weibo.com/mcxiaobing
@@ -56,11 +59,13 @@ protected void initData() {
progress_webview.setDownloadListener(new DownloadListener() {
@Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
- if (url != null && URLUtils.isNetworkImageUrl(url))
+ if (url != null && URLUtils.isNetworkImageUrl(url)) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
+ }
}
});
progress_webview.loadUrl(Urls.CSDN_BLOG_DAVID);
}
+
}
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/RecycleViewIntroduceActivity.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/RecycleViewIntroduceActivity.java
index 4363483..65904c3 100644
--- a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/RecycleViewIntroduceActivity.java
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/RecycleViewIntroduceActivity.java
@@ -8,6 +8,7 @@
* @OsChina空间: https://my.oschina.net/mcxiaobing
*/
+import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.ArrayAdapter;
@@ -27,18 +28,26 @@
public class RecycleViewIntroduceActivity extends BaseActivity {
private RecyclerView recycleview;
private RecyclerViewIntroduceAdapter adapter;
+ private List lists = new ArrayList();
@Override
protected void initView() {
setContentView(R.layout.activity_recycle_view_introduce);
recycleview = (RecyclerView) findViewById(R.id.recycleview);
+ lists.addAll(getData());
}
@Override
protected void initData() {
/**
- * listview绑定adapter
+ * 设置方向
*/
- adapter = new RecyclerViewIntroduceAdapter();
+ LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
+ linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
+ recycleview.setLayoutManager(linearLayoutManager);
+ /**
+ * RecyclerView绑定adapter
+ */
+ adapter = new RecyclerViewIntroduceAdapter(mContext,lists);
recycleview.setAdapter(adapter);
}
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/RefreshCustomFooterHeaderActivity.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/RefreshCustomFooterHeaderActivity.java
new file mode 100644
index 0000000..5f60d69
--- /dev/null
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/RefreshCustomFooterHeaderActivity.java
@@ -0,0 +1,148 @@
+package davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.activity;
+/*
+ * @Author :程序员小冰
+ * @新浪微博 :http://weibo.com/mcxiaobing
+ * @GitHub: https://github.com/QQ986945193
+ * @CSDN博客: http://blog.csdn.net/qq_21376985
+ * @OsChina空间: https://my.oschina.net/mcxiaobing
+ */
+import android.os.Handler;
+import android.os.Message;
+import android.support.v7.widget.LinearLayoutManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.R;
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.adapter.RecyclerViewIntroduceAdapter;
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.callback.OnTouchUpListener;
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.utils.DisplayUtils;
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.view.PullLoadRecyclerViewLayout;
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.widget.CustomDividerItemDecoration;
+
+import static com.tencent.open.utils.ThreadManager.init;
+
+/**
+ * Created by david zheng
+ *
+ * 可自动更改头部和底部的刷新与加载更多
+ */
+public class RefreshCustomFooterHeaderActivity extends BaseActivity implements OnTouchUpListener {
+ private PullLoadRecyclerViewLayout mLayout;
+ private RecyclerViewIntroduceAdapter mAdapter;
+
+ private View mHeaderView;
+ private View mFooterView;
+ @Override
+ protected void initView() {
+ setContentView(R.layout.activity_refresh_custom_footerheader);
+ mLayout = (PullLoadRecyclerViewLayout) findViewById(R.id.pull_load_layout);
+
+ init();
+ }
+ private List lists = new ArrayList();
+
+ @Override
+ protected void initData() {
+ lists.addAll(getData());
+ mAdapter = new RecyclerViewIntroduceAdapter(this, lists);
+ LayoutInflater inflater = LayoutInflater.from(RefreshCustomFooterHeaderActivity.this);
+ /**
+ * 引入头部和底部布局
+ */
+ mHeaderView = inflater.inflate(R.layout.co_refresh_header, null);
+ mFooterView = inflater.inflate(R.layout.co_refresh_footer, null);
+ mLayout.addHeaderView(mHeaderView, DisplayUtils.dip2px(RefreshCustomFooterHeaderActivity.this, 60));
+ mLayout.addFooterView(mFooterView, DisplayUtils.dip2px(RefreshCustomFooterHeaderActivity.this, 40));
+ mLayout.setMyRecyclerView(new LinearLayoutManager(RefreshCustomFooterHeaderActivity.this, LinearLayoutManager.VERTICAL, false),
+ mAdapter, true);
+ mLayout.setItemDivider(new CustomDividerItemDecoration(RefreshCustomFooterHeaderActivity.this, LinearLayoutManager.HORIZONTAL,
+ 1, getResources().getColor(android.R.color.black)));
+ mLayout.addOnTouchUpListener(this);
+ }
+ @Override
+ public void OnRefreshing() {
+ mLayout.setHeaderState(PullLoadRecyclerViewLayout.HEADER_STATE_REFRESHING);
+ onDataRefreshing();
+ }
+
+ @Override
+ public void OnLoading() {
+ mLayout.setFooterState(PullLoadRecyclerViewLayout.FOOTER_STATE_LOADING);
+ onDataLoadingMore();
+ }
+
+ private void onDataRefreshing() {
+ //自己的逻辑
+ mLayout.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ lists.clear();
+ lists.addAll(getData());
+ Log.e("onDataRefreshing", "onDataRefreshing");
+
+ onRefreshFinish(true);
+ }
+ }, 3000);
+ }
+
+ private void onDataLoadingMore() {
+ //自己的逻辑
+ mLayout.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ Log.e("onDataLoadingMore", "onDataLoadingMore");
+
+ lists.addAll(getData());
+ onLoadMoreFinish(true);
+ }
+ }, 2000);
+ }
+
+ private void onRefreshFinish(final boolean success) {
+ new Handler() {
+ @Override
+ public void handleMessage(Message message) {
+ mLayout.setHeaderState(success ? PullLoadRecyclerViewLayout.HEADER_STATE_COMPLETE :
+ PullLoadRecyclerViewLayout.HEADER_STATE_FAIL);
+ mAdapter.notifyDataSetChanged();
+ }
+ }.sendEmptyMessageDelayed(0, 100);
+ }
+
+ private void onLoadMoreFinish(final boolean success) {
+ new Handler() {
+ @Override
+ public void handleMessage(Message message) {
+ mLayout.setFooterState(success ? PullLoadRecyclerViewLayout.FOOTER_STATE_COMPLETE :
+ PullLoadRecyclerViewLayout.FOOTER_STATE_FAIL);
+ mAdapter.notifyDataSetChanged();
+
+ }
+ }.sendEmptyMessageDelayed(0, 100);
+ }
+
+
+ private List getData() {
+ List list = new ArrayList();
+ list.add("Hello world!");
+ list.add("CSDN:程序员小冰");
+ list.add("An Android Developer");
+ list.add("http://weibo.com/mcxiaobing");
+ list.add("http://git.oschina.net/MCXIAOBING");
+ list.add("https://github.com/QQ986945193");
+ list.add("An Android Developer");
+ list.add("http://weibo.com/mcxiaobing");
+ list.add("http://git.oschina.net/MCXIAOBING");
+ list.add("https://github.com/QQ986945193");
+ list.add("An Android Developer");
+ list.add("http://weibo.com/mcxiaobing");
+ list.add("http://git.oschina.net/MCXIAOBING");
+ list.add("https://github.com/QQ986945193");
+ return list;
+ }
+
+}
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/RefreshLoadMoreActivity.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/RefreshLoadMoreActivity.java
index ccc9650..05c04aa 100644
--- a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/RefreshLoadMoreActivity.java
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/RefreshLoadMoreActivity.java
@@ -29,6 +29,7 @@ public class RefreshLoadMoreActivity extends BaseActivity {
private Button btn_recycleview_auto_loadmore_swipe_sectionay;
private Button btn_recycleview_auto_loadmore_swipe_sectionfm;
private Button btn_recycleview_auto_loadmore_listview;
+ private Button btn_custom_footer_header_refresh;
@Override
@@ -47,6 +48,7 @@ protected void initView() {
btn_recycleview_auto_loadmore_swipe_sectionay = (Button) findViewById(R.id.btn_recycleview_auto_loadmore_swipe_sectionay);
btn_recycleview_auto_loadmore_swipe_sectionfm = (Button) findViewById(R.id.btn_recycleview_auto_loadmore_swipe_sectionfm);
btn_recycleview_auto_loadmore_listview = (Button) findViewById(R.id.btn_recycleview_auto_loadmore_listview);
+ btn_custom_footer_header_refresh = (Button) findViewById(R.id.btn_custom_footer_header_refresh);
}
@Override
@@ -115,6 +117,15 @@ public void onClick(View v) {
startActivity(PullRefreshRecycleViewActivity.class);
}
});
+ /**
+ * 可自动更改头部和底部的刷新与加载更多
+ */
+ btn_custom_footer_header_refresh.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startActivity(RefreshCustomFooterHeaderActivity.class);
+ }
+ });
/**
* recycleView嵌套listview刷新与加载更多
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/SplashActivity.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/SplashActivity.java
index b1da375..72f721a 100644
--- a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/SplashActivity.java
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/SplashActivity.java
@@ -60,6 +60,14 @@ protected void onCreate(Bundle savedInstanceState) {
ll_splash = (LinearLayout) findViewById(R.id.ll_splash);
+ /**
+ * 设置焦点触发,以防多个布局会出现显示中间的问题
+ */
+ ll_splash.setFocusable(true);
+ ll_splash.setFocusableInTouchMode(true);
+ ll_splash.requestFocus();
+
+
/**
* 第一种方法,利用handler自带的sendEmptyMessageDelayed()方法。
*/
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/TimeActivity.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/TimeActivity.java
new file mode 100644
index 0000000..996e401
--- /dev/null
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/TimeActivity.java
@@ -0,0 +1,139 @@
+package davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.activity;
+
+import android.os.Handler;
+import android.os.Message;
+import android.text.format.Time;
+import android.view.View;
+import android.widget.TextView;
+
+import java.util.Calendar;
+
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.R;
+
+/**
+ * @author :程序员小冰
+ * @新浪微博 :http://weibo.com/mcxiaobing
+ * @GitHub: https://github.com/QQ986945193
+ * @CSDN博客: http://blog.csdn.net/qq_21376985
+ * @交流Qq :986945193
+ */
+
+/**
+ * 获取走动的android时间
+ */
+public class TimeActivity extends BaseActivity implements View.OnClickListener{
+
+ private TextView data_tv;
+ private TextView data_tv2;
+ private Handler handler = new Handler(){
+ @Override
+ public void handleMessage(Message msg) {
+ super.handleMessage(msg);
+ switch (msg.what) {
+ case 1:
+ data_tv.setText(getData());
+ data_tv2.setText(getData2());
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ };
+
+
+ @Override
+ protected void initView() {
+ setContentView(R.layout.activity_time);
+
+ data_tv = (TextView) findViewById(R.id.data_tv);
+ data_tv2 = (TextView) findViewById(R.id.data_tv2);
+
+ new Thread(){
+
+ @Override
+ public void run() {
+ super.run();
+ while(true){
+ handler.sendEmptyMessage(1);
+ try {
+ sleep(1000);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+ }.start();
+
+ }
+
+ @Override
+ protected void initData() {
+
+ }
+
+
+
+ @Override
+ public void onClick(View v) {
+ switch (v.getId()) {
+ case R.id.data_tv:
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ public String getData(){
+ long time=System.currentTimeMillis();
+ final Calendar mCalendar=Calendar.getInstance();
+ mCalendar.setTimeInMillis(time);
+ int mHour=mCalendar.get(Calendar.HOUR);
+ int mMinuts=mCalendar.get(Calendar.MINUTE);
+ String mMinString = null;
+ if (mMinuts<10){ + mMinString = "0"+mMinuts; + }else{ + mMinString = ""+mMinuts; + } + return mHour+":"+mMinString; + } + + public String getData2(){ + Time time = new Time("GMT+8"); + time.setToNow(); + int year = time.year; + int month = time.month; + int day = time.monthDay; + int minute = time.minute; + int hour = time.hour+8; + int sec = time.second; + String mMinString = null; + String secString = null; + if (minute<10){ + mMinString = "0"+minute; + }else{ + mMinString = ""+minute; + } + + if (sec<10){ + secString = "0"+sec; + }else{ + secString = ""+sec; + } + + String str1 = "��ǰɦ��Ϊ��" + year + + "�� " + month + + "�� " + day + + "�� " + hour + + ":" + mMinString + + ": " + secString; + + return str1; + } + +} diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/UpDateAppActivity.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/UpDateAppActivity.java index 734ad0d..27b1fc5 100644 --- a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/UpDateAppActivity.java +++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/UpDateAppActivity.java @@ -8,12 +8,17 @@ * @OsChina空间: https://my.oschina.net/mcxiaobing */ +import android.app.AlertDialog; +import android.content.DialogInterface; import android.view.View; import android.widget.Button; +import android.widget.Toast; import butterknife.BindView; import butterknife.ButterKnife; import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.R; +import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.utils.ToastUtils; + /** * 升级APP软件的多种实现方式 @@ -23,6 +28,8 @@ public class UpDateAppActivity extends BaseActivity { Button btn1; @BindView(R.id.btn_2) Button btn2; + @BindView(R.id.btn_3) + Button btn_3; @Override protected void initView() { @@ -51,6 +58,29 @@ public void onClick(View v) { startActivity(LocalJsonUpdateAppActivity.class); } }); + /** + * 点击弹出一个dialog提示 + */ + btn_3.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + AlertDialog.Builder builder = new AlertDialog.Builder(UpDateAppActivity.this); + builder.setMessage("是否退出登录") + .setPositiveButton(getResources().getString(R.string.confirm), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, + int which) { + //这里执行我们的确定的操作方法 + ToastUtils.show(UpDateAppActivity.this,"你点击了确定", Toast.LENGTH_SHORT); + } + }).setNegativeButton(getResources().getString(R.string.cancel_), null).create(); + builder.show().setCanceledOnTouchOutside(true); + + } + }); } + + } diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/WebViewActivity.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/WebViewActivity.java index 4dd2b07..4cd3be5 100644 --- a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/WebViewActivity.java +++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/WebViewActivity.java @@ -5,6 +5,7 @@ import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.R; + /** * @author :程序员小冰 * @新浪微博 :http://weibo.com/mcxiaobing @@ -20,7 +21,6 @@ public class WebViewActivity extends BaseActivity { private Button btn_02; private Button btn_03; private Button btn_04; - private Button btn_05; @Override protected void initView() { @@ -29,7 +29,6 @@ protected void initView() { btn_02 = (Button) findViewById(R.id.btn_02); btn_03 = (Button) findViewById(R.id.btn_03); btn_04 = (Button) findViewById(R.id.btn_04); - btn_05 = (Button) findViewById(R.id.btn_05); } @Override @@ -72,15 +71,7 @@ public void onClick(View v) { startActivity(WebViewDetailActivity.class); } }); - /** - * webview的功能使用详解 - */ - btn_05.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - startActivity(WebViewDetailActivity.class); - } - }); + } } diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/WebViewDetailActivity.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/WebViewDetailActivity.java index 2a55d14..b5b53af 100644 --- a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/WebViewDetailActivity.java +++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/activity/WebViewDetailActivity.java @@ -18,10 +18,11 @@ import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; +import android.widget.Toast; import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.R; +import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.callback.ScanToolsCallback; import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.constant.Urls; -import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.utils.FileUtils; import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.utils.LogUtil; import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.utils.URLUtils; @@ -84,21 +85,24 @@ protected void initData() { // initWebViewSettings(); /*加载网页*/ - webview.loadUrl(Urls.CSDN_BLOG_DAVID); + webview.loadUrl(Urls.BAIDU_QRCODE_URL); + initQrcodeEvent(); /** * 设置调用系统浏览器下载文件 */ webview.setDownloadListener(new DownloadListener() { @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) { - Log.i("tag", "url=" + url); - Log.i("tag", "userAgent=" + userAgent); - Log.i("tag", "contentDisposition=" + contentDisposition); - Log.i("tag", "mimetype=" + mimetype); - Log.i("tag", "contentLength=" + contentLength); - Uri uri = Uri.parse(url); - Intent intent = new Intent(Intent.ACTION_VIEW, uri); - startActivity(intent); + if (url != null && URLUtils.isNetworkImageUrl(url)) { + Log.i("tag", "url=" + url); + Log.i("tag", "userAgent=" + userAgent); + Log.i("tag", "contentDisposition=" + contentDisposition); + Log.i("tag", "mimetype=" + mimetype); + Log.i("tag", "contentLength=" + contentLength); + Uri uri = Uri.parse(url); + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + startActivity(intent); + } } }); @@ -137,7 +141,7 @@ public void onPageFinished(WebView view, String url) { */ CookieManager cookieManager = CookieManager.getInstance(); String CookieStr = cookieManager.getCookie(url); - Log.e("webview的cookie", "Cookies="+CookieStr); + Log.e("webview的cookie", "Cookies=" + CookieStr); super.onPageFinished(view, url); // dialog.dismiss(); } @@ -163,5 +167,27 @@ public boolean onKey(View v, int keyCode, KeyEvent event) { } + /** + * 长按识别二维码的功能 + */ + private void initQrcodeEvent() { + webview.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + + //todo:调用扫描工具 + + ScanToolsCallback.scanCode(v, new ScanToolsCallback.ScanCall() { + @Override + public void getCode(String code) { + Toast.makeText(WebViewDetailActivity.this, code, Toast.LENGTH_SHORT).show(); + } + }); + return true; + } + }); + + + } } diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/adapter/ListViewIntroduceAdapter.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/adapter/ListViewIntroduceAdapter.java index 91e363d..a092388 100644 --- a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/adapter/ListViewIntroduceAdapter.java +++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/adapter/ListViewIntroduceAdapter.java @@ -1,6 +1,7 @@ package davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.adapter; import android.content.Context; +import android.content.Intent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -15,6 +16,7 @@ import java.util.List; import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.R; +import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.activity.MainActivity; import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.bean.ZhiHuBean; import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.utils.PicassoWithImageLoaderImageViewUtils; @@ -77,6 +79,10 @@ public View getView(int position, View convertView, ViewGroup parent) { if (bean.getImages() != null && bean.getImages().size() != 0) { PicassoWithImageLoaderImageViewUtils.displayImage(bean.getImages().get(0), holder.iv_introduce_img); } + /** + * 设置点击 + */ + convertView.setOnClickListener(new onItemClickListener("position url")); return convertView; } @@ -86,4 +92,31 @@ protected class ViewHolder { @ViewInject(R.id.iv_introduce_img) private ImageView iv_introduce_img; } + + /** + * 自定义点击事件 + */ + protected class onItemClickListener implements View.OnClickListener { + private String postUrl; + + public onItemClickListener(String postUrl) { + this.postUrl = postUrl; + } + + + @Override + public void onClick(View v) { + + if (postUrl != null && !(postUrl.equals(""))) { +// Intent startActivityIntent = new Intent(); +// startActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); +// startActivityIntent.setClass(mContext, MainActivity.class); + // 传参数,进入搜索界面 +// startActivityIntent.putExtra("buy_url", postUrl); +// mContext.startActivity(startActivityIntent); + + + } + } + } } diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/adapter/RecyclerViewIntroduceAdapter.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/adapter/RecyclerViewIntroduceAdapter.java index d623a4e..3f14b7c 100644 --- a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/adapter/RecyclerViewIntroduceAdapter.java +++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/adapter/RecyclerViewIntroduceAdapter.java @@ -1,9 +1,15 @@ package davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.adapter; +import android.content.Context; import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; +import java.util.List; + +import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.R; /** @@ -14,30 +20,46 @@ * @OsChina空间: https://my.oschina.net/mcxiaobing */ +/** + * RecycleView的详解adapter + */ +public class RecyclerViewIntroduceAdapter extends RecyclerView.Adapter {
-public class RecyclerViewIntroduceAdapter extends RecyclerView.Adapter {
+ private List datas;
+ private Context mContext;
+ public RecyclerViewIntroduceAdapter(Context mContext, List data) {
+ this.datas = data;
+ this.mContext = mContext;
+ }
@Override
- public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- return null;
+ public RecyclerViewIntroduceAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_listview_introduce, parent, false);
+ ViewHolder holder = new ViewHolder(view);
+ holder.tv_introduce_name = (TextView) view.findViewById(R.id.tv_introduce_name);
+ return holder;
}
@Override
- public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ public void onBindViewHolder(ViewHolder holder, int position) {
+ holder.tv_introduce_name.setText(datas.get(position));
}
@Override
public int getItemCount() {
- return 0;
+ return datas.size();
}
- class ViewHolder extends RecyclerView.ViewHolder{
+ public class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
}
+
+ public TextView tv_introduce_name;
+
}
}
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/app/MyApplication.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/app/MyApplication.java
index 58305a5..5ed1bc1 100644
--- a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/app/MyApplication.java
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/app/MyApplication.java
@@ -1,8 +1,10 @@
package davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.app;
import android.app.Application;
+import android.content.Context;
import android.graphics.Bitmap;
import android.os.Environment;
+import android.support.multidex.MultiDex;
import android.support.multidex.MultiDexApplication;
import android.widget.Toast;
@@ -44,7 +46,15 @@ public class MyApplication extends MultiDexApplication {
private BitmapUtils bitmapUtils;
private OkHttpUtils mOkHttpUtils;
-
+ /**
+ * 若是application继承了其他类,可以这样使用,突破65535
+ */
+ /* @Override
+ protected void attachBaseContext(Context base) {
+ super.attachBaseContext(base);
+ MultiDex.install(this);
+ }
+*/
@Override
public void onCreate() {
super.onCreate();
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/bean/UpdateAppBean.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/bean/UpdateAppBean.java
new file mode 100644
index 0000000..ff44436
--- /dev/null
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/bean/UpdateAppBean.java
@@ -0,0 +1,73 @@
+package davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.bean;
+
+import java.util.List;
+
+/**
+ * Created by david zheng on 2017年5月9日.
+ *
+ * https://github.com/QQ986945193
+ */
+
+public class UpdateAppBean {
+
+
+ /**
+ * status : success
+ * msg : [{"description":"你好。this is app description","downloadApkUrl":"http://192.168.1.36:8080/javaweb/download/dandroid.apk","versionCode":"2"}]
+ */
+
+ private String status;
+ private List msg;
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public List getMsg() {
+ return msg;
+ }
+
+ public void setMsg(List msg) {
+ this.msg = msg;
+ }
+
+ public static class MsgBean {
+ /**
+ * description : 你好。this is app description
+ * downloadApkUrl : http://192.168.1.36:8080/javaweb/download/dandroid.apk
+ * versionCode : 2
+ */
+
+ private String description;
+ private String downloadApkUrl;
+ private String versionCode;
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getDownloadApkUrl() {
+ return downloadApkUrl;
+ }
+
+ public void setDownloadApkUrl(String downloadApkUrl) {
+ this.downloadApkUrl = downloadApkUrl;
+ }
+
+ public String getVersionCode() {
+ return versionCode;
+ }
+
+ public void setVersionCode(String versionCode) {
+ this.versionCode = versionCode;
+ }
+ }
+}
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/callback/OnTouchUpListener.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/callback/OnTouchUpListener.java
new file mode 100644
index 0000000..6f5a157
--- /dev/null
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/callback/OnTouchUpListener.java
@@ -0,0 +1,12 @@
+package davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.callback;
+
+/**
+ * Created by david zheng
+ */
+public interface OnTouchUpListener {
+
+ void OnRefreshing();
+
+ void OnLoading();
+
+}
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/constant/Urls.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/constant/Urls.java
index 347ddca..9783156 100644
--- a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/constant/Urls.java
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/constant/Urls.java
@@ -52,6 +52,10 @@ public class Urls {
/*抓取的接口*/
public static final String ZHIHU_URL = "http://news-at.zhihu.com/api/4/news/before/20161122";
+ /*一个带有二维码图片的url*/
+ public static final String BAIDU_QRCODE_URL = "https://image.baidu.com/search/wiseala?tn=wiseala&active=1&ie=utf8&from=ala&fmpage=search&word=%E4%BA%8C%E7%BB%B4%E7%A0%81&pos=top";
+ /*自己写的一个升级app的servlet接口*/
+ public static final String CHECK_UPDATE_APP = "http://192.168.1.36:8080/javaweb/servlet/UpdateAppServlet";
}
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/fragment/MainFragment.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/fragment/MainFragment.java
index 7d8b0b5..6f86515 100644
--- a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/fragment/MainFragment.java
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/fragment/MainFragment.java
@@ -19,6 +19,7 @@
import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.activity.CreateFileActivity;
import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.activity.ListViewIntroduceActivity;
import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.activity.MoreAnimationStartActivity;
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.activity.RecycleViewIntroduceActivity;
import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.activity.SpinnerActivity;
import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.activity.SwipeRefreshListViewActivity;
import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.activity.SystemAppFourMethodActivity;
@@ -84,6 +85,7 @@ private void initData() {
listDatas.add("在手机中创建文件以及写入,读取,删除等功能");
listDatas.add("spinner(下拉框)的知识点详解");
listDatas.add("Toolbar和DrawableLayout的用法");
+ listDatas.add("RecycleView与adapter的详解");
mAdatper = new ArrayAdapter(mContext, android.R.layout.simple_list_item_1, listDatas);
lv_main_fragment.setAdapter(mAdatper);
@@ -151,6 +153,12 @@ public void onItemClick(AdapterView> parent, View view, int position, long id)
case 9:
intent = new Intent(mContext, ToolbarDrawerLayoutActivity.class);
break;
+ /**
+ *RecycleView与adapter的详解
+ */
+ case 10:
+ intent = new Intent(mContext, RecycleViewIntroduceActivity.class);
+ break;
}
if (intent != null) {
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/services/UpdateVersionDownloadService.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/services/UpdateVersionDownloadService.java
new file mode 100644
index 0000000..bacc590
--- /dev/null
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/services/UpdateVersionDownloadService.java
@@ -0,0 +1,298 @@
+package davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.services;
+/**
+ * @GitHub: https://github.com/QQ986945193
+ */
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.IBinder;
+import android.text.TextUtils;
+import android.util.Log;
+import android.widget.RemoteViews;
+import android.widget.Toast;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.R;
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.utils.LogUtil;
+
+/**
+ * 下载apk服务
+ */
+public class UpdateVersionDownloadService extends Service {
+
+ public static final String DOWNLOAD_PATH =
+ Environment.getExternalStorageDirectory().getAbsolutePath()+
+ "/downloads/";
+ public static final String TAG = "download";
+ private String url;//下载链接
+ private int length;//文件长度
+ private String fileName=null;//文件名
+ private Notification notification;
+ private RemoteViews contentView;
+ private NotificationManager notificationManager;
+
+ private static final int MSG_INIT = 0;
+ private static final int URL_ERROR = 1;
+ private static final int NET_ERROR = 2;
+ private static final int DOWNLOAD_SUCCESS = 3;
+ private Handler mHandler = new Handler(){
+ public void handleMessage(android.os.Message msg) {
+ switch (msg.what) {
+ case MSG_INIT:
+ length = (Integer) msg.obj;
+ new DownloadThread(url,length).start();
+ createNotification();
+ break;
+ case DOWNLOAD_SUCCESS:
+ //下载完成
+ notifyNotification(100, 100);
+ installApk(UpdateVersionDownloadService.this,new File(DOWNLOAD_PATH,fileName));
+ Toast.makeText(UpdateVersionDownloadService.this, "下载完成", Toast.LENGTH_SHORT).show();
+ break;
+ case URL_ERROR:
+ Toast.makeText(UpdateVersionDownloadService.this, "下载地址错误", Toast.LENGTH_SHORT).show();
+ break;
+ case NET_ERROR:
+ Toast.makeText(UpdateVersionDownloadService.this, "连接失败,请检查网络设置", Toast.LENGTH_SHORT).show();
+ }
+ };
+ };
+
+
+ public IBinder onBind(Intent arg0) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ if(intent != null){
+ url = intent.getStringExtra("url");
+ if(url != null && !TextUtils.isEmpty(url)){
+ new InitThread(url).start();
+ }else{
+ mHandler.sendEmptyMessage(URL_ERROR);
+ }
+
+ }
+ return super.onStartCommand(intent, flags, startId);
+ }
+
+ /**
+ * 初始化子线程
+ * @author dong
+ *
+ */
+ class InitThread extends Thread {
+ String url = "";
+
+ public InitThread(String url) {
+ this.url = url;
+ }
+ public void run() {
+ LogUtil.e("download_apk:"+url);
+// url = "http://download.cntv.cn/app/cntv/cbox_androidguanwang_v6.1.64.apk";
+ HttpURLConnection conn= null;
+ RandomAccessFile raf = null;
+ try {
+ //连接网络文件
+ URL url = new URL(this.url);
+ conn = (HttpURLConnection) url.openConnection();
+ conn.setConnectTimeout(20000);
+ conn.setReadTimeout(20000);
+ conn.setRequestMethod("GET");
+ int length = -1;
+
+ if(conn.getResponseCode() == 200 || conn.getResponseCode() == 206){
+ //获得文件长度
+ length = conn.getContentLength();
+ }
+ if(length <= 0){ + return; + } + File dir = new File(DOWNLOAD_PATH); + if(!dir.exists()){ + dir.mkdir(); + } + fileName = this.url.substring(this.url.lastIndexOf("/")+1, this.url.length()); + fileName = "davidapp"; + if(fileName==null && TextUtils.isEmpty(fileName) && !fileName.contains(".apk")){ + fileName = getPackageName()+".apk"; + fileName = "davidapp.apk"; + } + File file = new File(dir, fileName); + raf = new RandomAccessFile(file, "rwd"); + //设置文件长度 + raf.setLength(length); + mHandler.obtainMessage(MSG_INIT,length).sendToTarget(); + } catch (Exception e) { + mHandler.sendEmptyMessage(URL_ERROR); + e.printStackTrace(); + } finally{ + try { + if (conn!=null){ + conn.disconnect(); + } + if (raf!=null){ + raf.close(); + } + + } catch (Exception e) { + e.printStackTrace(); + + } + } + } + } + /** + * 下载线程 + * @author dong + * + */ + class DownloadThread extends Thread { + String url; + int length; + public DownloadThread(String url, int length) { + this.url = url; + this.length = length; + } + @Override + public void run() { + HttpURLConnection conn = null; + RandomAccessFile raf = null; + InputStream input = null; + try { + + URL url = new URL(this.url); + conn = (HttpURLConnection) url.openConnection(); + conn.setConnectTimeout(20000); + conn.setReadTimeout(20000); + conn.setRequestMethod("GET"); + //设置下载位置 + int start =0; + conn.setRequestProperty("Range", "bytes="+0+"-"+length); + //设置文件写入位置 + File file = new File(UpdateVersionDownloadService.DOWNLOAD_PATH,fileName); + raf = new RandomAccessFile(file, "rwd"); + raf.seek(start); + long mFinished = 0; + LogUtil.e("conn.getResponseCode()"+conn.getResponseCode()); + //开始下载 + if(conn.getResponseCode() == 200 || conn.getResponseCode() == 206 ){ + //LogUtil.i("下载开始了。。。"); + //读取数据 + input = conn.getInputStream(); + byte[] buffer = new byte[1024*4]; + int len = -1; + long speed = 0; + long time = System.currentTimeMillis(); + while((len = input.read(buffer)) != -1){ + //写入文件 + raf.write(buffer,0,len); + //把下载进度发送广播给Activity + mFinished += len; + speed += len; + if(System.currentTimeMillis() - time> 1000){
+ time = System.currentTimeMillis();
+
+ notifyNotification(mFinished,length);
+ Log.i(TAG, "mFinished=="+mFinished);
+ Log.i(TAG, "length=="+length);
+ Log.i(TAG, "speed=="+speed);
+ speed = 0;
+ }
+ }
+ mHandler.sendEmptyMessage(DOWNLOAD_SUCCESS);
+ Log.i(TAG, "下载完成了。。。");
+ }else{
+ Log.i(TAG, "下载出错了。。。");
+ mHandler.sendEmptyMessage(NET_ERROR);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally{
+ try {
+ if(conn != null){
+ conn.disconnect();
+ }
+ if(raf != null){
+ raf.close();
+ }
+ if(input != null ){
+ input.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ public void createNotification() {
+ notification = new Notification(
+ R.mipmap.ic_launcher,//应用的图标
+ "安装包正在下载...",
+ System.currentTimeMillis());
+ notification.flags = Notification.FLAG_ONGOING_EVENT;
+ //notification.flags = Notification.FLAG_AUTO_CANCEL;
+
+ /*** 自定义 Notification 的显示****/
+ contentView = new RemoteViews(getPackageName(), R.layout.notification_item);
+ contentView.setProgressBar(R.id.progress, 100, 0, false);
+ contentView.setTextViewText(R.id.tv_progress, "0%");
+ notification.contentView = contentView;
+
+ /*updateIntent = new Intent(this, AboutActivity.class);
+ updateIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ updateIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ pendingIntent = PendingIntent.getActivity(this, 0, updateIntent, 0);
+ notification.contentIntent = pendingIntent;*/
+ notification.flags = Notification.FLAG_AUTO_CANCEL;
+ notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+
+ //设置notification的PendingIntent
+ /*Intent intt = new Intent(this, MainActivity.class);
+ PendingIntent pi = PendingIntent.getActivity(this,100, intt,Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+ notification.contentIntent = pi;*/
+
+ notificationManager.notify(R.layout.notification_item, notification);
+ }
+
+ private void notifyNotification(long percent,long length){
+
+ contentView.setTextViewText(R.id.tv_progress, (percent*100/length)+"%");
+ contentView.setProgressBar(R.id.progress, (int)length,(int)percent, false);
+ notification.contentView = contentView;
+ notificationManager.notify(R.layout.notification_item, notification);
+ }
+ /**
+ * 安装apk
+ *
+ * @param context 上下文
+ * @param file APK文件
+ */
+ public static void installApk(Context context, File file) {
+ Intent intent = new Intent();
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setAction(Intent.ACTION_VIEW);
+ intent.setDataAndType(Uri.fromFile(file),
+ "application/vnd.android.package-archive");
+ context.startActivity(intent);
+ }
+}
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/utils/CalendarUtil.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/utils/CalendarUtil.java
new file mode 100644
index 0000000..50d7535
--- /dev/null
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/utils/CalendarUtil.java
@@ -0,0 +1,110 @@
+package davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.utils;
+
+
+import android.text.format.Time;
+
+import java.util.Calendar;
+import java.util.TimeZone;
+
+/*
+ * @Author :David
+ * @新浪微博 :http://weibo.com/mcxiaobing
+ * @GitHub: https://github.com/QQ986945193
+ */
+public class CalendarUtil {
+
+
+ /**
+ * 获取时分
+ */
+ public static String getHourMin() {
+ long time = System.currentTimeMillis();
+ final Calendar mCalendar = Calendar.getInstance();
+ mCalendar.setTimeInMillis(time);
+ int mHour = mCalendar.get(Calendar.HOUR);
+ int mMinuts = mCalendar.get(Calendar.MINUTE);
+ String mMinString = null;
+ if (mMinuts < 10) { + mMinString = "0" + mMinuts; + } else { + mMinString = "" + mMinuts; + } + return mHour + ":" + mMinString; + } + + + /** + * 获取时分 + */ + public static String getYearMonthDay() { + Time time = new Time("GMT+8"); + time.setToNow(); + int year = time.year; + int month = time.month; + int day = time.monthDay; + return year + "." + month + "." + day; + } + + /** + * 获取星期几 + */ + public static String getCurrentWeek() { + final Calendar c = Calendar.getInstance(); + c.setTimeZone(TimeZone.getTimeZone("GMT+8:00")); +// mYear = String.valueOf(c.get(Calendar.YEAR)); // 获取当前年份 +// mMonth = String.valueOf(c.get(Calendar.MONTH) + 1);// 获取当前月份 +// mDay = String.valueOf(c.get(Calendar.DAY_OF_MONTH));// 获取当前月份的日期号码 + String mWay = String.valueOf(c.get(Calendar.DAY_OF_WEEK)); + if ("1".equals(mWay)) { + mWay = "日"; + } else if ("2".equals(mWay)) { + mWay = "一"; + } else if ("3".equals(mWay)) { + mWay = "二"; + } else if ("4".equals(mWay)) { + mWay = "三"; + } else if ("5".equals(mWay)) { + mWay = "四"; + } else if ("6".equals(mWay)) { + mWay = "五"; + } else if ("7".equals(mWay)) { + mWay = "六"; + } +// return mYear + "年" + mMonth + "月" + mDay + "日" + "/星期" + mWay; + return "星期" + mWay; + + } + +// public String getData2() { +// Time time = new Time("GMT+8"); +// time.setToNow(); +// int year = time.year; +// int month = time.month; +// int day = time.monthDay; +// int minute = time.minute; +// int hour = time.hour + 8; +// int sec = time.second; +// String mMinString = null; +// String secString = null; +// if (minute < 10) { +// mMinString = "0" + minute; +// } else { +// mMinString = "" + minute; +// } +// +// if (sec < 10) { +// secString = "0" + sec; +// } else { +// secString = "" + sec; +// } +// +// String str1 = "��ǰɦ��Ϊ��" + year + +// "�� " + month + +// "�� " + day + +// "�� " + hour + +// ":" + mMinString + +// ": " + secString; +// +// return str1; +// } +} diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/utils/NetworkAvailableUtils.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/utils/NetworkAvailableUtils.java index 367af67..dc0d759 100644 --- a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/utils/NetworkAvailableUtils.java +++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/utils/NetworkAvailableUtils.java @@ -9,6 +9,7 @@ import android.telephony.TelephonyManager; import android.util.Log; +import java.net.Inet4Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; @@ -34,7 +35,7 @@ public class NetworkAvailableUtils { * 判断是否联网 * * @param context - * @return * //判断是否联网 返回true 则表示已经联网否则联网了否则没有联网 + * @return * //判断是否联网 返回true 则表示已经联网。否则联网了否则没有联网 */ public static boolean isNetworkAvailable(Context context) { ConnectivityManager cm = (ConnectivityManager) context @@ -73,7 +74,7 @@ public static boolean isGpsEnabled(Context context) { * 三、判断WIFI是否打开 * * @param context - * @return + * @return 若是返回true 则表示已经连接了wifi,否则则表示没有连接wifi */ public static boolean isWifiEnabled(Context context) { @@ -134,11 +135,10 @@ public static String getConnectWifiSsid(Context context) { return wifiInfo.getSSID(); } - /** - * 获得 本地 IP地址 + * 获得 本地 ip地址以ipV6的方式显示 */ - private String getLocalIPAddress() { //获得 本地IP地址 + public static String getLocalIP6Address() { //获得 本地IP地址 try { for (Enumeration en = NetworkInterface.getNetworkInterfaces();
en.hasMoreElements(); ) {
@@ -153,6 +153,27 @@ private String getLocalIPAddress() { //获得 本地IP地址
} catch (SocketException ex) {
LogUtil.E(ex.toString());
}
+
+ return null;
+ }
+
+ /**
+ * 获得本地地址 ip地址以ipV4的方式显示
+ */
+ public static String getLocalIP4Address() {
+ try {
+ for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
+ NetworkInterface intf = en.nextElement();
+ for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
+ InetAddress inetAddress = enumIpAddr.nextElement();
+ if (!inetAddress.isLoopbackAddress() && (inetAddress instanceof Inet4Address)) {
+ return inetAddress.getHostAddress().toString();
+ }
+ }
+ }
+ } catch (SocketException e) {
+ e.printStackTrace();
+ }
return null;
}
}
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/utils/VersionUtil.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/utils/VersionUtil.java
index 0ce98ba..6aab63c 100644
--- a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/utils/VersionUtil.java
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/utils/VersionUtil.java
@@ -3,7 +3,7 @@
import android.os.Build;
/**
- * Created by Neal on 2014年10月30日.
+ * Created by DAVID on .
*/
public class VersionUtil {
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/view/OnMeasureCustomListView.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/view/OnMeasureCustomListView.java
new file mode 100644
index 0000000..8e99583
--- /dev/null
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/view/OnMeasureCustomListView.java
@@ -0,0 +1,39 @@
+package davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.view;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.ListView;
+
+/**
+ *http://weibo.com/mcxiaobing
+ */
+public class OnMeasureCustomListView extends ListView {
+ public OnMeasureCustomListView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public OnMeasureCustomListView(Context context) {
+ super(context);
+ }
+
+ public OnMeasureCustomListView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /***
+ *
+ * 改变高度 其中onMeasure函数决定了组件显示的高度与宽度;
+ * makeMeasureSpec函数中第一个函数决定布局空间的大小,第二个参数是布局模式
+ * MeasureSpec.AT_MOST的意思就是子控件需要多大的控件就扩展到多大的空间
+ * 之后在ScrollView中添加这个组件就OK了,同样的道理,ListView也适用。
+ */
+ @Override
+ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>> 2,
+ MeasureSpec.AT_MOST);
+ super.onMeasure(widthMeasureSpec, expandSpec);
+ }
+
+
+
+}
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/view/PullLoadRecyclerViewLayout.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/view/PullLoadRecyclerViewLayout.java
new file mode 100644
index 0000000..20e5477
--- /dev/null
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/view/PullLoadRecyclerViewLayout.java
@@ -0,0 +1,476 @@
+package davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.view;
+/*
+ * @Author :程序员小冰
+ * @新浪微博 :http://weibo.com/mcxiaobing
+ * @GitHub: https://github.com/QQ986945193
+ * @CSDN博客: http://blog.csdn.net/qq_21376985
+ * @OsChina空间: https://my.oschina.net/mcxiaobing
+ */
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.drawable.AnimationDrawable;
+import android.support.v4.view.NestedScrollingParent;
+import android.support.v4.view.NestedScrollingParentHelper;
+import android.support.v7.widget.DefaultItemAnimator;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.StaggeredGridLayoutManager;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.AnimationUtils;
+import android.view.animation.LinearInterpolator;
+import android.view.animation.RotateAnimation;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.R;
+import davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.callback.OnTouchUpListener;
+
+/**
+ * Created by david zheng
+ */
+public class PullLoadRecyclerViewLayout extends LinearLayout implements NestedScrollingParent {
+
+ private static final int ANIM_INTERVAL = 300;
+
+ public static final int HEADER_STATE_INIT = 0x10;
+ public static final int HEADER_STATE_RELEASE_REFRESH = 0x11;
+ public static final int HEADER_STATE_REFRESHING = 0x12;
+ public static final int HEADER_STATE_COMPLETE = 0x13;
+ public static final int HEADER_STATE_FAIL = 0x14;
+
+ public static final int FOOTER_STATE_INIT = 0x20;
+ public static final int FOOTER_STATE_RELEASE_LOAD = 0x21;
+ public static final int FOOTER_STATE_LOADING = 0x22;
+ public static final int FOOTER_STATE_COMPLETE = 0x23;
+ public static final int FOOTER_STATE_FAIL = 0x24;
+
+ private Context context = null;
+ private NestedScrollingParentHelper helper = null;
+ //move total
+ private int totalY = 0;
+ private LinearLayout headerLayout = null;
+ private MyRecyclerView myRecyclerView = null;
+ private LinearLayout footerLayout = null;
+ private OnTouchUpListener onTouchUpListener = null;
+ private boolean isfling = false;
+ private int headerHeight = 0;
+ private int footerHeight = 0;
+
+ private ImageView mHeaderImg;
+ private TextView mHeaderTextView;
+ private ImageView mFooterImageView;
+ private TextView mFooterTextView;
+ private ProgressBar mFooterProgressBar;
+
+ // 下拉箭头的转180°动画
+ private RotateAnimation rotateAnimation;
+
+ private boolean isFirst = true;
+
+ public PullLoadRecyclerViewLayout(Context context) {
+ super(context);
+ this.context = context;
+ inital();
+ }
+
+ public PullLoadRecyclerViewLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ this.context = context;
+ inital();
+ }
+
+ private void inital() {
+ helper = new NestedScrollingParentHelper(this);
+ headerLayout = new LinearLayout(context);
+ myRecyclerView = new MyRecyclerView(context);
+ footerLayout = new LinearLayout(context);
+ setOrientation(VERTICAL);
+ headerLayout.setOrientation(VERTICAL);
+ footerLayout.setOrientation(VERTICAL);
+ addView(this.headerLayout, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
+ addView(this.myRecyclerView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+ addView(this.footerLayout, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
+
+ rotateAnimation = (RotateAnimation) AnimationUtils.loadAnimation(context, R.anim.reverse_anim);
+ // 添加匀速转动动画
+ LinearInterpolator lir = new LinearInterpolator();
+ rotateAnimation.setInterpolator(lir);
+ }
+
+ public void setMyRecyclerView(RecyclerView.LayoutManager layoutManager, RecyclerView.Adapter adapter) {
+ setMyRecyclerView(layoutManager, adapter, false);
+ }
+
+ public void setMyRecyclerView(RecyclerView.LayoutManager layoutManager, RecyclerView.Adapter adapter, boolean fixed) {
+ myRecyclerView.setMyLayoutManager(layoutManager);
+ myRecyclerView.setAdapter(adapter);
+ myRecyclerView.setHasFixedSize(fixed);
+ }
+
+ public void addHeaderView(View headerView, int headerHeight) {
+ this.headerHeight = headerHeight;
+ this.headerLayout.removeAllViews();
+ this.headerLayout.addView(headerView);
+ mHeaderImg = (ImageView) headerView.findViewById(R.id.refresh_header_img);
+ mHeaderTextView = (TextView) headerView.findViewById(R.id.refresh_header_txt);
+ LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, headerHeight);
+ layoutParams.topMargin = -headerHeight;
+ this.headerLayout.setLayoutParams(layoutParams);
+ setHeaderState(HEADER_STATE_INIT);
+ }
+
+ public void addFooterView(View footerView, int footerHeight) {
+ this.footerHeight = footerHeight;
+ this.footerLayout.removeAllViews();
+ this.footerLayout.addView(footerView);
+ mFooterImageView = (ImageView) footerView.findViewById(R.id.co_pull_to_load_image);
+ mFooterTextView = (TextView) footerView.findViewById(R.id.co_pull_to_load_text);
+ mFooterProgressBar = (ProgressBar) footerView.findViewById(R.id.co_pull_to_load_progress);
+ this.footerLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, footerHeight));
+ setFooterState(FOOTER_STATE_INIT);
+ }
+
+ public void setScrollTo(int fromY, int toY) {
+ smoothScrollTo((float) fromY, (float) toY);
+ }
+
+ public void setItemDivider(RecyclerView.ItemDecoration itemDecoration) {
+ myRecyclerView.addItemDecoration(itemDecoration);
+ }
+
+ public int getTotal() {
+ return -totalY;
+ }
+
+
+ public void setIsScrollLoad(boolean isScrollLoad) {
+ myRecyclerView.isScrollLoad = isScrollLoad;
+ }
+
+ public boolean isScrollLoad() {
+ return myRecyclerView.isScrollLoad;
+ }
+
+ public void setIsScrollRefresh(boolean isScrollRefresh) {
+ myRecyclerView.isScrollRefresh = isScrollRefresh;
+ }
+
+ public boolean isScrollRefresh() {
+ return myRecyclerView.isScrollRefresh;
+ }
+
+ public void setRecyclerViewScrollToPosition(int position) {
+ myRecyclerView.scrollToPosition(position);
+ }
+
+ public void addOnTouchUpListener(OnTouchUpListener onTouchUpListener) {
+ this.onTouchUpListener = onTouchUpListener;
+ }
+
+ public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
+ return true;
+ }
+
+ public void onNestedScrollAccepted(View child, View target, int axes) {
+ helper.onNestedScrollAccepted(child, target, axes);
+ }
+
+ //parent view intercept child view scroll
+ public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
+ if (totalY < 0 && myRecyclerView.isOrientation(0) || totalY> 0 && myRecyclerView.isOrientation(1)) {
+ isfling = true;
+ }
+
+ if (dy> 0) {//手指上滑,当recyclerview到底了,需要处理上拉加载
+ if (!myRecyclerView.canScrollVertically(1)) {//不能继续上拉了,parent处理footerView
+ totalY += dy;
+ if (totalY>= footerHeight) {
+ setFooterState(FOOTER_STATE_RELEASE_LOAD);
+ }
+ scrollTo(0, totalY);
+ consumed[1] = dy;
+ } else {//可以继续下拉
+ if (totalY < 0) {//header已出现,先要处理header + if (-totalY < headerHeight) { + setHeaderState(HEADER_STATE_INIT); + } + if (totalY + dy> 0) {//header消失,交由子View处理
+ consumed[1] = -totalY;
+ scrollTo(0, 0);
+ } else {//header依然存在,parent处理
+ totalY += dy;
+ scrollTo(0, totalY);
+ consumed[1] = dy;
+ }
+ } else {
+ scrollTo(0, 0);
+ consumed[1] = 0;
+ }
+ }
+ return;
+ }
+ if (dy < 0) {//下拉,当recyclerview到顶了,需要处理下拉刷新 + if (!myRecyclerView.canScrollVertically(-1)) {//不能继续下拉,parent处理headerView + totalY += dy; + if (-totalY>= headerHeight) {
+ setHeaderState(HEADER_STATE_RELEASE_REFRESH);
+ }
+ scrollTo(0, totalY);
+ consumed[1] = dy;
+ } else {
+ if (totalY> 0) {//footer已出现
+ if (totalY < footerHeight) { + setFooterState(FOOTER_STATE_INIT); + } + if (totalY + dy < 0) {//footer消失,剩下的交由子View处理 + consumed[1] = -totalY; + scrollTo(0, 0); + } else {//footer依然在,parent处理 + totalY += dy; + scrollTo(0, totalY); + consumed[1] = dy; + } + } else { + scrollTo(0, 0); + consumed[1] = 0; + } + } + return; + } + } + + //while child view move finish + //dyUnconsumed < 0 move down + //dyUnconsumed> 0 move up
+ public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
+ if (dyUnconsumed != 0) {
+ totalY += dyUnconsumed;
+ scrollTo(0, totalY);
+ }
+ }
+
+ public void onStopNestedScroll(View child) {
+ helper.onStopNestedScroll(child);
+ if (onTouchUpListener != null) {
+ isfling = false;
+ if (this.getTotal()>= headerHeight) {
+ this.setScrollTo(this.getTotal(), headerHeight);
+ if (!this.isScrollRefresh()) {
+ this.setIsScrollRefresh(true);
+ postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ onTouchUpListener.OnRefreshing();
+ }
+ }, ANIM_INTERVAL);
+ }
+ } else if (-this.getTotal()>= footerHeight) {
+ this.setScrollTo(this.getTotal(), -footerHeight);
+ if (!this.isScrollLoad()) {
+ this.setIsScrollLoad(true);
+ postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ onTouchUpListener.OnLoading();
+ }
+ }, ANIM_INTERVAL);
+ }
+ } else {
+ this.setScrollTo(0, 0);
+ }
+ }
+ }
+
+ public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {
+ return isfling;
+ }
+
+ public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
+ return isfling;
+ }
+
+ public int getNestedScrollAxes() {
+ return helper.getNestedScrollAxes();
+ }
+
+ private void smoothScrollTo(float fromY, float toY) {
+ ValueAnimator animator = ValueAnimator.ofFloat(new float[]{fromY, toY});
+ if (fromY == toY) {
+ animator.setDuration(0);
+ } else {
+ animator.setDuration(ANIM_INTERVAL);
+ }
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ public void onAnimationUpdate(ValueAnimator animation) {
+ int to = (int) (-((Float) animation.getAnimatedValue()).floatValue());
+ scrollTo(0, to);
+ totalY = to;
+ }
+ });
+ animator.start();
+ }
+
+ private class MyRecyclerView extends RecyclerView {
+ private StaggeredGridLayoutManager staggeredGridLayoutManager = null;
+ private LinearLayoutManager linearLayoutManager = null;
+ private GridLayoutManager gridLayoutManager = null;
+ private boolean isScrollLoad = false;
+ private boolean isScrollRefresh = false;
+
+ public MyRecyclerView(Context context) {
+ super(context);
+ setVerticalFadingEdgeEnabled(false);
+ setHorizontalFadingEdgeEnabled(false);
+ setVerticalScrollBarEnabled(false);
+ setHorizontalScrollBarEnabled(false);
+ setOverScrollMode(OVER_SCROLL_NEVER);
+ setItemAnimator(new DefaultItemAnimator());
+ }
+
+ private void setMyLayoutManager(LayoutManager layoutManager) {
+ if (layoutManager instanceof StaggeredGridLayoutManager) {
+ staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
+ } else if (layoutManager instanceof GridLayoutManager) {
+ gridLayoutManager = (GridLayoutManager) layoutManager;
+ } else if (layoutManager instanceof LinearLayoutManager) {
+ linearLayoutManager = (LinearLayoutManager) layoutManager;
+ }
+ setLayoutManager(layoutManager);
+ if (!isVertical()) {
+ throw new NullPointerException("vertical!");
+ }
+ }
+
+ //orientation
+ // 0 menas down
+ // 1 means up
+ private boolean isOrientation(int orientation) {
+ if (orientation == 0)
+ return isCanPullDown();
+ else if (orientation == 1)
+ return isCanPullUp();
+ return false;
+ }
+
+ private boolean isCanPullDown() {
+ return !canScrollVertically(-1);
+ }
+
+ private boolean isCanPullUp() {
+ return !canScrollVertically(1);
+ }
+
+ private boolean isVertical() {
+ if (staggeredGridLayoutManager != null)
+ return staggeredGridLayoutManager.getOrientation() == StaggeredGridLayoutManager.VERTICAL;
+ else if (linearLayoutManager != null)
+ return linearLayoutManager.getOrientation() == LinearLayoutManager.VERTICAL;
+ else if (gridLayoutManager != null)
+ return gridLayoutManager.getOrientation() == GridLayoutManager.VERTICAL;
+ return false;
+ }
+ }
+
+ public void setHeaderState(int state) {
+ switch (state) {
+ case HEADER_STATE_INIT:
+ stopDrawableAnimation();
+ mHeaderTextView.setText(context.getString(R.string.pull_to_refresh));
+ break;
+ case HEADER_STATE_RELEASE_REFRESH:
+ mHeaderTextView.setText(context.getString(R.string.release_to_refresh));
+ break;
+ case HEADER_STATE_REFRESHING:
+ startDrawableAnimation();
+ mHeaderTextView.setText(context.getString(R.string.refreshing));
+ break;
+ case HEADER_STATE_COMPLETE:
+ stopDrawableAnimation();
+ mHeaderTextView.setText(context.getString(R.string.refresh_succeed));
+ this.setIsScrollRefresh(false);
+ setScrollTo(getTotal(), 0);
+ postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ setHeaderState(HEADER_STATE_INIT);
+ }
+ }, ANIM_INTERVAL);
+ break;
+ }
+ }
+
+ public void setFooterState(int state) {
+ switch (state) {
+ case FOOTER_STATE_INIT:
+ mFooterTextView.setText(context.getString(R.string.pullup_to_load));
+ mFooterImageView.clearAnimation();
+ mFooterProgressBar.setVisibility(View.GONE);
+ mFooterImageView.setVisibility(View.VISIBLE);
+ isFirst = true;
+ break;
+ case FOOTER_STATE_LOADING:
+ mFooterTextView.setText(context.getString(R.string.loading));
+ mFooterImageView.clearAnimation();
+ mFooterImageView.setVisibility(View.INVISIBLE);
+ mFooterProgressBar.setVisibility(View.VISIBLE);
+ break;
+ case FOOTER_STATE_RELEASE_LOAD:
+ mFooterTextView.setText(context.getString(R.string.release_to_load));
+ if (isFirst) {//不控制,动画一直播
+ isFirst = false;
+ mFooterImageView.startAnimation(rotateAnimation);
+ }
+ break;
+ case FOOTER_STATE_COMPLETE:
+ mFooterTextView.setText(context.getString(R.string.load_succeed));
+ this.setIsScrollLoad(false);
+ setScrollTo(getTotal(), 0);
+ postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ setFooterState(FOOTER_STATE_INIT);
+ }
+ }, ANIM_INTERVAL);
+ break;
+ case FOOTER_STATE_FAIL:
+ mFooterTextView.setText(context.getString(R.string.load_fail));
+ this.setIsScrollLoad(false);
+ setScrollTo(getTotal(), 0);
+ postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ setFooterState(FOOTER_STATE_INIT);
+ }
+ }, ANIM_INTERVAL);
+ break;
+ }
+ }
+
+
+ private void startDrawableAnimation() {
+ if (mHeaderImg != null) {
+ AnimationDrawable animationDrawable = (AnimationDrawable) mHeaderImg.getBackground();
+ animationDrawable.start();
+ }
+ }
+
+ private void stopDrawableAnimation() {
+ if (mHeaderImg != null) {
+ AnimationDrawable animationDrawable = (AnimationDrawable) mHeaderImg.getBackground();
+ if (animationDrawable != null) {
+ animationDrawable.stop();
+ animationDrawable.selectDrawable(0);//最后停留在第一帧
+ }
+// if(Build.VERSION.SDK_INT> Build.VERSION_CODES.LOLLIPOP) {
+// animationDrawable.setVisible(true, true);
+// }else {
+// animationDrawable.setVisible(false, true);
+// }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/widget/CustomDividerItemDecoration.java b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/widget/CustomDividerItemDecoration.java
new file mode 100644
index 0000000..ed77012
--- /dev/null
+++ b/app/src/main/java/davidandroidprojecttools/qq986945193/com/davidandroidprojecttools/widget/CustomDividerItemDecoration.java
@@ -0,0 +1,116 @@
+package davidandroidprojecttools.qq986945193.com.davidandroidprojecttools.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.support.v4.content.ContextCompat;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+
+/**
+ * Created by david
+ */
+public class CustomDividerItemDecoration extends RecyclerView.ItemDecoration {
+ private Drawable mDivider;
+ private int mDividerHeight = 2;
+ private int mOrientation;
+ private Paint paint;
+ private static final int[] ATTRS = new int[] {android.R.attr.listDivider};
+
+ public CustomDividerItemDecoration(Context context, int orientation) {
+ if (orientation != LinearLayoutManager.VERTICAL &&
+ orientation != LinearLayoutManager.HORIZONTAL) {
+ throw new IllegalArgumentException("RecyclerView设置的LayoutManager不正确");
+ }
+ mOrientation = orientation;
+ TypedArray ta = context.obtainStyledAttributes(ATTRS);
+ mDivider = ta.getDrawable(0);
+ ta.recycle();
+ }
+
+ public CustomDividerItemDecoration(Context context, String color) {
+ this(context, LinearLayoutManager.VERTICAL, 1, Color.parseColor(color));
+ }
+
+ public CustomDividerItemDecoration(Context context, int orientation, int resId) {
+ this(context, orientation);
+ mDivider = ContextCompat.getDrawable(context, resId);
+ mDividerHeight = mDivider.getIntrinsicHeight();
+ }
+
+ public CustomDividerItemDecoration(Context context, int orientation, int dividerHeight, int dividerColor) {
+ this(context, orientation);
+ mDividerHeight = dividerHeight;
+ paint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ paint.setColor(dividerColor);
+ paint.setStyle(Paint.Style.FILL);
+ }
+
+ @Override
+ public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
+ super.getItemOffsets(outRect, view, parent, state);
+ final int childSize = parent.getAdapter().getItemCount();
+ int childPostion = parent.getChildAdapterPosition(view);
+ if(childPostion == childSize - 1) {// || view instance ArrowRefreshHeader
+ outRect.set(0, 0, 0, 0);
+ }else {
+ outRect.set(0, 0, 0, mDividerHeight);
+ }
+ }
+
+ @Override
+ public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
+ super.onDraw(c, parent, state);
+ if (mOrientation == LinearLayoutManager.HORIZONTAL) {
+ drawHorizontal(c, parent);
+ }else {
+ drawVertical(c, parent);
+ }
+ }
+
+ private void drawHorizontal(Canvas canvas, RecyclerView parent) {
+ final int left = parent.getPaddingLeft();
+ final int right = parent.getMeasuredWidth() - parent.getPaddingRight();
+ final int childSize = parent.getChildCount();
+ for(int i=0;i
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_local_json_update_app.xml b/app/src/main/res/layout/activity_local_json_update_app.xml
index 0fccf52..d338f24 100644
--- a/app/src/main/res/layout/activity_local_json_update_app.xml
+++ b/app/src/main/res/layout/activity_local_json_update_app.xml
@@ -5,4 +5,9 @@
android:orientation="vertical">
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_refresh_custom_footerheader.xml b/app/src/main/res/layout/activity_refresh_custom_footerheader.xml
new file mode 100644
index 0000000..367482e
--- /dev/null
+++ b/app/src/main/res/layout/activity_refresh_custom_footerheader.xml
@@ -0,0 +1,10 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_refresh_load_more.xml b/app/src/main/res/layout/activity_refresh_load_more.xml
index 35ef951..61a3a08 100644
--- a/app/src/main/res/layout/activity_refresh_load_more.xml
+++ b/app/src/main/res/layout/activity_refresh_load_more.xml
@@ -53,6 +53,12 @@
android:layout_height="wrap_content"
android:text="带有自动加载与上拉刷新的activity recycleView" />
+
+