diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..5176974
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..bf0bb80
--- /dev/null
+++ b/.project
@@ -0,0 +1,33 @@
+
+
+ TrineaAndroidDemo
+
+
+
+
+
+ com.android.ide.eclipse.adt.ResourceManagerBuilder
+
+
+
+
+ com.android.ide.eclipse.adt.PreCompilerBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ com.android.ide.eclipse.adt.ApkBuilder
+
+
+
+
+
+ com.android.ide.eclipse.adt.AndroidNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
new file mode 100644
index 0000000..c5a8e6c
--- /dev/null
+++ b/AndroidManifest.xml
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/proguard.cfg b/proguard.cfg
new file mode 100644
index 0000000..12dd039
--- /dev/null
+++ b/proguard.cfg
@@ -0,0 +1,36 @@
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keepclasseswithmembernames class * {
+ native ;
+}
+
+-keepclasseswithmembernames class * {
+ public (android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembernames class * {
+ public (android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+ public static final android.os.Parcelable$Creator *;
+}
diff --git a/project.properties b/project.properties
new file mode 100644
index 0000000..ec74fa2
--- /dev/null
+++ b/project.properties
@@ -0,0 +1,15 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-14
+android.library.reference.1=../trinea-android-common
diff --git a/res/drawable-hdpi/icon.png b/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..3db76f6
Binary files /dev/null and b/res/drawable-hdpi/icon.png differ
diff --git a/res/drawable-hdpi/icon_stop.png b/res/drawable-hdpi/icon_stop.png
new file mode 100644
index 0000000..d2fbdc4
Binary files /dev/null and b/res/drawable-hdpi/icon_stop.png differ
diff --git a/res/drawable-ldpi/icon.png b/res/drawable-ldpi/icon.png
new file mode 100644
index 0000000..6b92542
Binary files /dev/null and b/res/drawable-ldpi/icon.png differ
diff --git a/res/drawable-ldpi/icon_stop.png b/res/drawable-ldpi/icon_stop.png
new file mode 100644
index 0000000..d2fbdc4
Binary files /dev/null and b/res/drawable-ldpi/icon_stop.png differ
diff --git a/res/drawable-mdpi/icon.png b/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000..6b92542
Binary files /dev/null and b/res/drawable-mdpi/icon.png differ
diff --git a/res/drawable-mdpi/icon_stop.png b/res/drawable-mdpi/icon_stop.png
new file mode 100644
index 0000000..d2fbdc4
Binary files /dev/null and b/res/drawable-mdpi/icon_stop.png differ
diff --git a/res/drawable-mdpi/image1.jpg b/res/drawable-mdpi/image1.jpg
new file mode 100644
index 0000000..cd0ced6
Binary files /dev/null and b/res/drawable-mdpi/image1.jpg differ
diff --git a/res/drawable-mdpi/image2.jpg b/res/drawable-mdpi/image2.jpg
new file mode 100644
index 0000000..b7c0706
Binary files /dev/null and b/res/drawable-mdpi/image2.jpg differ
diff --git a/res/drawable-mdpi/image3.jpg b/res/drawable-mdpi/image3.jpg
new file mode 100644
index 0000000..0dec967
Binary files /dev/null and b/res/drawable-mdpi/image3.jpg differ
diff --git a/res/drawable/button_press.9.png b/res/drawable/button_press.9.png
new file mode 100644
index 0000000..af917e5
Binary files /dev/null and b/res/drawable/button_press.9.png differ
diff --git a/res/drawable/button_press_selector.xml b/res/drawable/button_press_selector.xml
new file mode 100644
index 0000000..8404068
--- /dev/null
+++ b/res/drawable/button_press_selector.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/jpg1.jpg b/res/drawable/jpg1.jpg
new file mode 100644
index 0000000..7925e7a
Binary files /dev/null and b/res/drawable/jpg1.jpg differ
diff --git a/res/drawable/jpg2.jpg b/res/drawable/jpg2.jpg
new file mode 100644
index 0000000..a5fa10c
Binary files /dev/null and b/res/drawable/jpg2.jpg differ
diff --git a/res/drawable/jpg3.jpg b/res/drawable/jpg3.jpg
new file mode 100644
index 0000000..45db28f
Binary files /dev/null and b/res/drawable/jpg3.jpg differ
diff --git a/res/drawable/jpg4.jpg b/res/drawable/jpg4.jpg
new file mode 100644
index 0000000..b9ec507
Binary files /dev/null and b/res/drawable/jpg4.jpg differ
diff --git a/res/layout/border_scroll_view_demo.xml b/res/layout/border_scroll_view_demo.xml
new file mode 100644
index 0000000..f194e73
--- /dev/null
+++ b/res/layout/border_scroll_view_demo.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/broadcast_receiver_demo.xml b/res/layout/broadcast_receiver_demo.xml
new file mode 100644
index 0000000..b9eef86
--- /dev/null
+++ b/res/layout/broadcast_receiver_demo.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/demo_list.xml b/res/layout/demo_list.xml
new file mode 100644
index 0000000..adf2b56
--- /dev/null
+++ b/res/layout/demo_list.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/download_manager_demo.xml b/res/layout/download_manager_demo.xml
new file mode 100644
index 0000000..a54ddb8
--- /dev/null
+++ b/res/layout/download_manager_demo.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/drop_down_listview_demo.xml b/res/layout/drop_down_listview_demo.xml
new file mode 100644
index 0000000..e958da7
--- /dev/null
+++ b/res/layout/drop_down_listview_demo.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/image_list_item.xml b/res/layout/image_list_item.xml
new file mode 100644
index 0000000..fa1fbb9
--- /dev/null
+++ b/res/layout/image_list_item.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/search_view_demo.xml b/res/layout/search_view_demo.xml
new file mode 100644
index 0000000..3ea40c8
--- /dev/null
+++ b/res/layout/search_view_demo.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/search_view_demo_title.xml b/res/layout/search_view_demo_title.xml
new file mode 100644
index 0000000..230ad7b
--- /dev/null
+++ b/res/layout/search_view_demo_title.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/service_demo.xml b/res/layout/service_demo.xml
new file mode 100644
index 0000000..b0644c0
--- /dev/null
+++ b/res/layout/service_demo.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/slide_one_page_gallery_demo.xml b/res/layout/slide_one_page_gallery_demo.xml
new file mode 100644
index 0000000..8614595
--- /dev/null
+++ b/res/layout/slide_one_page_gallery_demo.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/trinea_info.xml b/res/layout/trinea_info.xml
new file mode 100644
index 0000000..f82dcb2
--- /dev/null
+++ b/res/layout/trinea_info.xml
@@ -0,0 +1,9 @@
+
diff --git a/res/layout/view_pager_demo.xml b/res/layout/view_pager_demo.xml
new file mode 100644
index 0000000..0a232c6
--- /dev/null
+++ b/res/layout/view_pager_demo.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/view_pager_fragment_demo1.xml b/res/layout/view_pager_fragment_demo1.xml
new file mode 100644
index 0000000..dd9a9cc
--- /dev/null
+++ b/res/layout/view_pager_fragment_demo1.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/view_pager_multi_fragment_demo.xml b/res/layout/view_pager_multi_fragment_demo.xml
new file mode 100644
index 0000000..777308d
--- /dev/null
+++ b/res/layout/view_pager_multi_fragment_demo.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..3c275c2
--- /dev/null
+++ b/res/values-zh-rCN/strings.xml
@@ -0,0 +1,33 @@
+
+
+
+ 发送广播
+ 发送Local广播
+ 发送有序广播
+ 发送Sticky广播
+
+ 启动普通服务
+ 停止普通服务
+ 启动Intent Service
+ 绑定服务
+ 增加绑定服务的count属性
+ 获取绑定服务的count属性
+ 解除绑定服务
+ 启动AIDL服务
+ 停止AIDL服务
+
+ 点击下载美丽说APK
+ 已下载过,点击重新下载
+ 下载失败,点击重新下载
+ 下载进度:
+ 美丽说
+ 开始下载
+ 下载失败
+ 等待下载
+ 暂停
+ 下载中
+ 文件将下载到:
+
+ 更新于:
+
+
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
new file mode 100644
index 0000000..0d2c4cc
--- /dev/null
+++ b/res/values/attrs.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
new file mode 100644
index 0000000..1fec666
--- /dev/null
+++ b/res/values/colors.xml
@@ -0,0 +1,11 @@
+
+
+
+
+ #A72309
+
+ #729045
+
+ #5200D5
+
+
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
new file mode 100644
index 0000000..b4e5a4f
--- /dev/null
+++ b/res/values/dimens.xml
@@ -0,0 +1,12 @@
+
+
+
+ 45dp
+ 15dp
+ 8dp
+ 60dp
+ 40dp
+ 16sp
+ 35dp
+
+
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
new file mode 100644
index 0000000..9dc0fdd
--- /dev/null
+++ b/res/values/strings.xml
@@ -0,0 +1,45 @@
+
+
+
+ Trinea Android Demo
+
+ Drop Down And Load More ListView Demo
+ onBottom onTop ScrollView Demo
+ SearchView Demo
+ DownloadManager Demo
+ Slide One Page Gallery Demo
+ ViewPager Demo
+ ViewPager Multi Fragment Demo
+ Intent Demo
+ Service Demo
+ BroadcastReceiver Demo
+
+ send general broadcast
+ send local broadcast
+ send ordered broadcast
+ send sticky broadcast
+
+ start general service
+ stop_general service
+ start intent service
+ bound service
+ operate_bound service
+ get bound service pro
+ unbound service
+ start aidl service
+ stop aidl service
+
+ click to download
+ downloaded, click to download again
+ download fail, click to download again
+ download tip:
+ MeiLiShuo
+ begin Download
+ download Fail
+ download Peding
+ Pause
+ downloading
+ file will be saved to sdcard, the path is:
+
+ updated at:
+
diff --git a/res/values/styles.xml b/res/values/styles.xml
new file mode 100644
index 0000000..4dba0d0
--- /dev/null
+++ b/res/values/styles.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/cn/trinea/android/demo/BaseActivity.java b/src/cn/trinea/android/demo/BaseActivity.java
new file mode 100644
index 0000000..6650275
--- /dev/null
+++ b/src/cn/trinea/android/demo/BaseActivity.java
@@ -0,0 +1,39 @@
+package cn.trinea.android.demo;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.MenuItem;
+import android.widget.Button;
+import cn.trinea.android.demo.utils.AppUtils;
+
+/**
+ * BaseActivity
+ *
+ * @author Trinea 2013-6-1
+ */
+public class BaseActivity extends Activity {
+
+ private Button trineaInfoTv;
+
+ protected void onCreate(Bundle savedInstanceState, int layoutResID) {
+ super.onCreate(savedInstanceState);
+ setContentView(layoutResID);
+
+ AppUtils.initTrineaInfo(this, trineaInfoTv, getClass());
+
+ ActionBar bar = getActionBar();
+ bar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_HOME_AS_UP);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home: {
+ onBackPressed();
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/cn/trinea/android/demo/BorderScrollViewDemo.java b/src/cn/trinea/android/demo/BorderScrollViewDemo.java
new file mode 100644
index 0000000..af69208
--- /dev/null
+++ b/src/cn/trinea/android/demo/BorderScrollViewDemo.java
@@ -0,0 +1,53 @@
+package cn.trinea.android.demo;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.view.Display;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import cn.trinea.android.common.view.BorderScrollView;
+import cn.trinea.android.common.view.BorderScrollView.OnBorderListener;
+
+/**
+ * BorderScrollViewDemo
+ *
+ * @author Trinea 2013-5-27
+ */
+public class BorderScrollViewDemo extends BaseActivity {
+
+ private BorderScrollView borderScrollView;
+ private TextView textView1;
+ private TextView textView2;
+
+ private Context context;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState, R.layout.border_scroll_view_demo);
+
+ context = getApplicationContext();
+
+ borderScrollView = (BorderScrollView)findViewById(R.id.scroll_view);
+ borderScrollView.setOnBorderListener(new OnBorderListener() {
+
+ @Override
+ public void onTop() {
+ // may be done multi times, u should control it
+ Toast.makeText(context, "has reached top", Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ public void onBottom() {
+ // may be done multi times, u should control it
+ Toast.makeText(context, "has reached bottom", Toast.LENGTH_SHORT).show();
+ }
+ });
+ textView1 = (TextView)findViewById(R.id.text1);
+ textView2 = (TextView)findViewById(R.id.text2);
+
+ Display display = getWindowManager().getDefaultDisplay();
+ textView1.setHeight(display.getHeight() / 2);
+ textView2.setHeight(display.getHeight() / 2);
+ }
+}
diff --git a/src/cn/trinea/android/demo/BroadcastReceiverDemo.java b/src/cn/trinea/android/demo/BroadcastReceiverDemo.java
new file mode 100644
index 0000000..61f637f
--- /dev/null
+++ b/src/cn/trinea/android/demo/BroadcastReceiverDemo.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2012 Trinea.cn All right reserved. This software is the
+ * confidential and proprietary information of Trinea.cn ("Confidential
+ * Information"). You shall not disclose such Confidential Information and shall
+ * use it only in accordance with the terms of the license agreement you entered
+ * into with Trinea.cn.
+ */
+package cn.trinea.android.demo;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.Toast;
+
+/**
+ * BroadcastReceiver Demo,包括普通广播、本地广播、有序广播、粘性广播
+ *
+ * @author Trinea 2012-9-20
+ */
+public class BroadcastReceiverDemo extends BaseActivity {
+
+ private final static String ACTION_GENERAL_SEND = "cn.trinea.android.demo.BroadcastReceiverDemo.sendGeneralBroadcast";
+ private final static String ACTION_LOCAL_SEND = "cn.trinea.android.demo.BroadcastReceiverDemo.sendLocalBroadcast";
+ private final static String ACTION_ORDERED_SEND = "cn.trinea.android.demo.BroadcastReceiverDemo.sendOrderedBroadcast";
+ private final static String ACTION_STICKY_SEND = "cn.trinea.android.demo.BroadcastReceiverDemo.sendStickyBroadcast";
+
+ private final static String MSG_KEY = "msg";
+ private final static String RUSULT_MSG_KEY = "resultMsg";
+ private boolean isStickyRegister = false;
+
+ private MyBroadcastReceiver generalReceiver;
+ private OrderedBroadcastReceiverPriorityHigh orderedReceiverHigh;
+ private OrderedBroadcastReceiverPriorityMedium orderedReceiverMed;
+ private OrderedBroadcastReceiverPriorityLow orderedReceiverLow;
+ private MyBroadcastReceiver stickyReceiver;
+
+ private Button sendGeneralBtn;
+ private Button sendLocalBtn;
+ private Button sendOrderedBtn;
+ private Button sendStickyBtn;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState, R.layout.broadcast_receiver_demo);
+
+ generalReceiver = new MyBroadcastReceiver();
+ orderedReceiverHigh = new OrderedBroadcastReceiverPriorityHigh();
+ orderedReceiverMed = new OrderedBroadcastReceiverPriorityMedium();
+ orderedReceiverLow = new OrderedBroadcastReceiverPriorityLow();
+ stickyReceiver = new MyBroadcastReceiver();
+
+ sendGeneralBtn = (Button)findViewById(R.id.sendGeneralBroadcast);
+ sendGeneralBtn.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ Intent i = new Intent(ACTION_GENERAL_SEND);
+ i.putExtra(MSG_KEY, "普通广播告知好声音马上开始了啦");
+ sendBroadcast(i);
+ }
+ });
+
+ sendLocalBtn = (Button)findViewById(R.id.sendLocalBroadcast);
+ sendLocalBtn.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ Intent i = new Intent(ACTION_LOCAL_SEND);
+ i.putExtra(MSG_KEY, "Local广播告知好声音马上开始了啦");
+ }
+ });
+
+ sendOrderedBtn = (Button)findViewById(R.id.sendOrderedBroadcast);
+ sendOrderedBtn.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ Intent i = new Intent(ACTION_ORDERED_SEND);
+ i.putExtra(MSG_KEY, "有序广播告知好声音马上开始了啦");
+ // 发送本地广播,设置最终接受广播的Receiver
+ sendOrderedBroadcast(i, null, new OrderedBroadcastReceiverResultReceiver(), null, Activity.RESULT_OK,
+ null, null);
+ }
+ });
+
+ sendStickyBtn = (Button)findViewById(R.id.sendStickyBroadcast);
+ sendStickyBtn.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ Intent i = new Intent(ACTION_STICKY_SEND);
+ i.putExtra(MSG_KEY, "Sticky广播告知好声音马上开始了啦");
+ sendStickyBroadcast(i);
+ // 广播发送两秒后才注册Receiver
+ new Handler().postDelayed(new Runnable() {
+
+ @Override
+ public void run() {
+ isStickyRegister = true;
+ registerReceiver(stickyReceiver, new IntentFilter(ACTION_STICKY_SEND));
+ }
+ }, 2000);
+ }
+ });
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ unregisterReceiver(generalReceiver);
+ unregisterReceiver(orderedReceiverHigh);
+ unregisterReceiver(orderedReceiverMed);
+ unregisterReceiver(orderedReceiverLow);
+ if (isStickyRegister) {
+ unregisterReceiver(stickyReceiver);
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ registerReceiver(generalReceiver, new IntentFilter(ACTION_GENERAL_SEND));
+
+ IntentFilter high = new IntentFilter(ACTION_ORDERED_SEND);
+ high.setPriority(100);
+ IntentFilter med = new IntentFilter(ACTION_ORDERED_SEND);
+ med.setPriority(-1);
+ IntentFilter low = new IntentFilter(ACTION_ORDERED_SEND);
+ low.setPriority(-100);
+ registerReceiver(orderedReceiverHigh, high);
+ registerReceiver(orderedReceiverMed, med);
+ registerReceiver(orderedReceiverLow, low);
+ }
+
+ public class MyBroadcastReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Toast.makeText(context, intent.getStringExtra(MSG_KEY), Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ public class OrderedBroadcastReceiverPriorityHigh extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Toast.makeText(context, "优先级最高的接收者接收到广播,内容为:" + intent.getStringExtra(MSG_KEY), Toast.LENGTH_SHORT).show();
+ // 修改广播结果
+ getResultExtras(true).putString(RUSULT_MSG_KEY, "High");
+ }
+ }
+
+ public class OrderedBroadcastReceiverPriorityMedium extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Toast.makeText(context,
+ "优先级中等的接收者接收到广播,内容为:" + intent.getStringExtra(MSG_KEY) + ",上一个接收者为:"
+ + getResultExtras(true).getString(RUSULT_MSG_KEY), Toast.LENGTH_SHORT).show();
+ getResultExtras(true).putString(RUSULT_MSG_KEY, "Medium");
+ // 取消广播
+ abortBroadcast();
+ }
+ }
+
+ public class OrderedBroadcastReceiverPriorityLow extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Toast.makeText(context,
+ "优先级最低的接收者接收到广播,内容为:" + intent.getStringExtra(MSG_KEY) + ",上一个接收者为:"
+ + getResultExtras(true).getString(RUSULT_MSG_KEY), Toast.LENGTH_SHORT).show();
+ getResultExtras(true).putString(RUSULT_MSG_KEY, "Low");
+ }
+ }
+
+ public class OrderedBroadcastReceiverResultReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Toast.makeText(context,
+ "结果接收者接收到广播,内容为:" + intent.getStringExtra(MSG_KEY) + ",上一个接收者为:"
+ + getResultExtras(true).getString(RUSULT_MSG_KEY), Toast.LENGTH_SHORT).show();
+ }
+ }
+}
diff --git a/src/cn/trinea/android/demo/DemoList.java b/src/cn/trinea/android/demo/DemoList.java
new file mode 100644
index 0000000..2398b17
--- /dev/null
+++ b/src/cn/trinea/android/demo/DemoList.java
@@ -0,0 +1,81 @@
+package cn.trinea.android.demo;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+
+import cn.trinea.android.common.service.impl.ImageCache;
+
+import android.app.ActionBar;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+/**
+ * demo list list
+ *
+ * @author Trinea 2012-6-17
+ */
+public class DemoList extends BaseActivity {
+
+ public static final String TAG = "DemoList";
+
+ private static final String[] mStrings = { "DropDownListViewDemo", "onBottom onTop ScrollView Demo",
+ "DownloadManager Demo", "SearchView Demo", "ViewPager Multi Fragment Demo\r\n(ViewPager一屏多Fragment)",
+ "Slide One Page Gallery Demo", "ViewPager Demo", "Service Demo", "BroadcastReceiver Demo" };
+
+ private static final int total = mStrings.length - 1;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState, R.layout.demo_list);
+
+ ActionBar bar = getActionBar();
+ bar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME);
+
+ LinkedList mListItems = new LinkedList();
+ mListItems.addAll(Arrays.asList(mStrings));
+ ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, mListItems);
+
+ ListView demoListView = (ListView)findViewById(R.id.simpleListView);
+ demoListView.setAdapter(adapter);
+ demoListView.setOnItemClickListener(new OnItemClickListener() {
+
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ if (position == total - 8) {
+ Intent intent = new Intent(DemoList.this, DropDownListViewDemo.class);
+ startActivity(intent);
+ } else if (position == total - 7) {
+ Intent intent = new Intent(DemoList.this, BorderScrollViewDemo.class);
+ startActivity(intent);
+ } else if (position == total - 6) {
+ Intent intent = new Intent(DemoList.this, DownloadManagerDemo.class);
+ startActivity(intent);
+ } else if (position == total - 5) {
+ Intent intent = new Intent(DemoList.this, SearchViewDemo.class);
+ startActivity(intent);
+ } else if (position == total - 4) {
+ Intent intent = new Intent(DemoList.this, ViewPagerMulTiFragmentDemo.class);
+ startActivity(intent);
+ } else if (position == total - 3) {
+ Intent intent = new Intent(DemoList.this, SlideOnePageGalleryDemo.class);
+ startActivity(intent);
+ } else if (position == total - 2) {
+ Intent intent = new Intent(DemoList.this, ViewPagerDemo.class);
+ startActivity(intent);
+ } else if (position == total - 1) {
+ Intent intent = new Intent(DemoList.this, ServiceDemo.class);
+ startActivity(intent);
+ } else if (position == total) {
+ Intent intent = new Intent(DemoList.this, BroadcastReceiverDemo.class);
+ startActivity(intent);
+ }
+ }
+ });
+ }
+}
diff --git a/src/cn/trinea/android/demo/DownloadManagerDemo.java b/src/cn/trinea/android/demo/DownloadManagerDemo.java
new file mode 100644
index 0000000..221d03b
--- /dev/null
+++ b/src/cn/trinea/android/demo/DownloadManagerDemo.java
@@ -0,0 +1,317 @@
+package cn.trinea.android.demo;
+
+import java.io.File;
+import java.text.DecimalFormat;
+
+import android.app.DownloadManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Message;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+import android.widget.Toast;
+import cn.trinea.android.demo.utils.DownloadManagerPro;
+
+/**
+ * DownloadManagerDemo
+ *
+ * @author Trinea 2013-5-9
+ */
+public class DownloadManagerDemo extends BaseActivity {
+
+ public static final String DOWNLOAD_FOLDER_NAME = "Trinea";
+ public static final String DOWNLOAD_FILE_NAME = "MeiLiShuo.apk";
+
+ public static final String APK_URL = "http://img.meilishuo.net/css/images/AndroidShare/Meilishuo_3.6.1_10006.apk";
+
+ private Button downloadButton;
+ private ProgressBar downloadProgress;
+ private TextView downloadTip;
+ private TextView downloadSize;
+ private TextView downloadPrecent;
+ private Button downloadCancel;
+
+ private DownloadManager downloadManager;
+ private DownloadManagerPro downloadManagerPro;
+ private long downloadId = 0;
+
+ private Context context;
+ private MyHandler handler;
+
+ private DownloadChangeObserver downloadObserver;
+ private CompleteReceiver completeReceiver;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState, R.layout.download_manager_demo);
+
+ context = getApplicationContext();
+ handler = new MyHandler();
+ downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
+ downloadManagerPro = new DownloadManagerPro(downloadManager);
+
+ // see android mainfest.xml, accept minetype of cn.trinea.download.file
+ Intent intent = getIntent();
+ if (intent != null) {
+ /**
+ * below android 4.2, intent.getDataString() is file:///storage/sdcard1/Trinea/MeLiShuo.apk
+ * equal or above 4.2 intent.getDataString() is content://media/external/file/29669
+ */
+ Uri data = intent.getData();
+ if (data != null) {
+ Toast.makeText(getApplicationContext(), data.toString(), Toast.LENGTH_LONG).show();
+ }
+ }
+
+ initView();
+ initData();
+
+ downloadObserver = new DownloadChangeObserver();
+ completeReceiver = new CompleteReceiver();
+ /** register download success broadcast **/
+ registerReceiver(completeReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ /** observer download change **/
+ getContentResolver().registerContentObserver(DownloadManagerPro.CONTENT_URI, true, downloadObserver);
+ updateView();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ getContentResolver().unregisterContentObserver(downloadObserver);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ unregisterReceiver(completeReceiver);
+ }
+
+ private void initView() {
+ downloadButton = (Button)findViewById(R.id.download_button);
+ downloadCancel = (Button)findViewById(R.id.download_cancel);
+ downloadProgress = (ProgressBar)findViewById(R.id.download_progress);
+ downloadTip = (TextView)findViewById(R.id.download_tip);
+ downloadTip.setText(getString(R.string.tip_download_file)
+ + Environment.getExternalStoragePublicDirectory(DOWNLOAD_FOLDER_NAME));
+ downloadSize = (TextView)findViewById(R.id.download_size);
+ downloadPrecent = (TextView)findViewById(R.id.download_precent);
+ }
+
+ private void initData() {
+ /**
+ * get download id from preferences.
+ * if download id bigger than 0, means it has been downloaded, then query status and show right text;
+ */
+ downloadId = PreferencesUtils.getLongPreferences(context, PreferencesUtils.KEY_NAME_DOWNLOAD_ID);
+ updateView();
+ downloadButton.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ File folder = new File(DOWNLOAD_FOLDER_NAME);
+ if (!folder.exists() || !folder.isDirectory()) {
+ folder.mkdirs();
+ }
+
+ DownloadManager.Request request = new DownloadManager.Request(Uri.parse(APK_URL));
+ request.setDestinationInExternalPublicDir(DOWNLOAD_FOLDER_NAME, DOWNLOAD_FILE_NAME);
+ request.setTitle(getString(R.string.download_notification_title));
+ request.setDescription("meilishuo desc");
+ request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
+ request.setVisibleInDownloadsUi(false);
+ // request.allowScanningByMediaScanner();
+ // request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
+ // request.setShowRunningNotification(false);
+ // request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
+ request.setMimeType("application/cn.trinea.download.file");
+ downloadId = downloadManager.enqueue(request);
+ /** save download id to preferences **/
+ PreferencesUtils.putLongPreferences(context, PreferencesUtils.KEY_NAME_DOWNLOAD_ID, downloadId);
+ updateView();
+ }
+ });
+ downloadCancel.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ downloadManager.remove(downloadId);
+ updateView();
+ }
+ });
+ }
+
+ /**
+ * install app
+ *
+ * @param context
+ * @param filePath
+ * @return whether apk exist
+ */
+ public static boolean install(Context context, String filePath) {
+ Intent i = new Intent(Intent.ACTION_VIEW);
+ File file = new File(filePath);
+ if (file != null && file.length() > 0 && file.exists() && file.isFile()) {
+ i.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android.package-archive");
+ i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(i);
+ return true;
+ }
+ return false;
+ }
+
+ class DownloadChangeObserver extends ContentObserver {
+
+ public DownloadChangeObserver(){
+ super(handler);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ updateView();
+ }
+
+ }
+
+ class CompleteReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ /**
+ * get the id of download which have download success, if the id is my id and it's status is successful,
+ * then install it
+ **/
+ long completeDownloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
+ if (completeDownloadId == downloadId) {
+ initData();
+ updateView();
+ // if download successful, install apk
+ if (downloadManagerPro.getStatusById(downloadId) == DownloadManager.STATUS_SUCCESSFUL) {
+ String apkFilePath = new StringBuilder(Environment.getExternalStorageDirectory().getAbsolutePath()).append(File.separator)
+ .append(DOWNLOAD_FOLDER_NAME)
+ .append(File.separator)
+ .append(DOWNLOAD_FILE_NAME)
+ .toString();
+ install(context, apkFilePath);
+ }
+ }
+ }
+ };
+
+ public void updateView() {
+ int[] bytesAndStatus = downloadManagerPro.getBytesAndStatus(downloadId);
+ handler.sendMessage(handler.obtainMessage(0, bytesAndStatus[0], bytesAndStatus[1], bytesAndStatus[2]));
+ }
+
+ /**
+ * MyHandler
+ *
+ * @author Trinea 2012-12-18
+ */
+ private class MyHandler extends Handler {
+
+ @Override
+ public void handleMessage(Message msg) {
+ super.handleMessage(msg);
+
+ switch (msg.what) {
+ case 0:
+ int status = (Integer)msg.obj;
+ if (isDownloading(status)) {
+ downloadProgress.setVisibility(View.VISIBLE);
+ downloadProgress.setMax(0);
+ downloadProgress.setProgress(0);
+ downloadButton.setVisibility(View.GONE);
+ downloadSize.setVisibility(View.VISIBLE);
+ downloadPrecent.setVisibility(View.VISIBLE);
+ downloadCancel.setVisibility(View.VISIBLE);
+
+ if (msg.arg2 < 0) {
+ downloadProgress.setIndeterminate(true);
+ downloadPrecent.setText("0%");
+ downloadSize.setText("0M/0M");
+ } else {
+ downloadProgress.setIndeterminate(false);
+ downloadProgress.setMax(msg.arg2);
+ downloadProgress.setProgress(msg.arg1);
+ downloadPrecent.setText(getNotiPercent(msg.arg1, msg.arg2));
+ downloadSize.setText(getAppSize(msg.arg1) + "/" + getAppSize(msg.arg2));
+ }
+ } else {
+ downloadProgress.setVisibility(View.GONE);
+ downloadProgress.setMax(0);
+ downloadProgress.setProgress(0);
+ downloadButton.setVisibility(View.VISIBLE);
+ downloadSize.setVisibility(View.GONE);
+ downloadPrecent.setVisibility(View.GONE);
+ downloadCancel.setVisibility(View.GONE);
+
+ if (status == DownloadManager.STATUS_FAILED) {
+ downloadButton.setText(getString(R.string.app_status_download_fail));
+ } else if (status == DownloadManager.STATUS_SUCCESSFUL) {
+ downloadButton.setText(getString(R.string.app_status_downloaded));
+ } else {
+ downloadButton.setText(getString(R.string.app_status_download));
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ static final DecimalFormat DOUBLE_DECIMAL_FORMAT = new DecimalFormat("0.##");
+
+ public static final int MB_2_BYTE = 1024 * 1024;
+ public static final int KB_2_BYTE = 1024;
+
+ /**
+ * @param size
+ * @return
+ */
+ public static CharSequence getAppSize(long size) {
+ if (size <= 0) {
+ return "0M";
+ }
+
+ if (size >= MB_2_BYTE) {
+ return new StringBuilder(16).append(DOUBLE_DECIMAL_FORMAT.format((double)size / MB_2_BYTE)).append("M");
+ } else if (size >= KB_2_BYTE) {
+ return new StringBuilder(16).append(DOUBLE_DECIMAL_FORMAT.format((double)size / KB_2_BYTE)).append("K");
+ } else {
+ return size + "B";
+ }
+ }
+
+ public static String getNotiPercent(long progress, long max) {
+ int rate = 0;
+ if (progress <= 0 || max <= 0) {
+ rate = 0;
+ } else if (progress > max) {
+ rate = 100;
+ } else {
+ rate = (int)((double)progress / max * 100);
+ }
+ return new StringBuilder(16).append(rate).append("%").toString();
+ }
+
+ public static boolean isDownloading(int downloadManagerStatus) {
+ return downloadManagerStatus == DownloadManager.STATUS_RUNNING
+ || downloadManagerStatus == DownloadManager.STATUS_PAUSED
+ || downloadManagerStatus == DownloadManager.STATUS_PENDING;
+ }
+}
diff --git a/src/cn/trinea/android/demo/DropDownListViewDemo.java b/src/cn/trinea/android/demo/DropDownListViewDemo.java
new file mode 100644
index 0000000..6da04fa
--- /dev/null
+++ b/src/cn/trinea/android/demo/DropDownListViewDemo.java
@@ -0,0 +1,99 @@
+package cn.trinea.android.demo;
+
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.LinkedList;
+
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ArrayAdapter;
+
+import cn.trinea.android.common.view.DropDownListView;
+import cn.trinea.android.common.view.DropDownListView.OnDropDownListener;
+
+/**
+ * DropDownListViewDemo
+ *
+ * @author Trinea 2013-6-1
+ */
+public class DropDownListViewDemo extends BaseActivity {
+
+ private LinkedList listItems = null;
+ private DropDownListView listView = null;
+ private ArrayAdapter adapter;
+
+ private String[] mStrings = { "Aaaaaa", "Bbbbbb", "Cccccc", "Dddddd", "Eeeeee", "Ffffff", "Gggggg",
+ "Hhhhhh", "Iiiiii", "Jjjjjj", "Kkkkkk", "Llllll", "Mmmmmm", "Nnnnnn", };
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState, R.layout.drop_down_listview_demo);
+
+ listView = (DropDownListView)findViewById(R.id.list_view);
+ // set drop down listener
+ listView.setOnDropDownListener(new OnDropDownListener() {
+
+ @Override
+ public void onDropDown() {
+ new GetDataTask(true).execute();
+ }
+ });
+
+ // set on bottom listener
+ listView.setOnBottomListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ new GetDataTask(false).execute();
+ }
+ });
+
+ listItems = new LinkedList();
+ listItems.addAll(Arrays.asList(mStrings));
+ adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, listItems);
+ listView.setAdapter(adapter);
+ }
+
+ private class GetDataTask extends AsyncTask {
+
+ private boolean isDropDown;
+
+ public GetDataTask(boolean isDropDown){
+ this.isDropDown = isDropDown;
+ }
+
+ @Override
+ protected String[] doInBackground(Void... params) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ ;
+ }
+ return mStrings;
+ }
+
+ @Override
+ protected void onPostExecute(String[] result) {
+
+ if (isDropDown) {
+ listItems.addFirst("Added after drop down");
+ adapter.notifyDataSetChanged();
+
+ // should call onDropDownComplete function of DropDownListView at end of drop down complete.
+ SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd HH:mm:ss");
+ listView.onDropDownComplete(getString(R.string.update_at) + dateFormat.format(new Date()));
+ } else {
+ listItems.add("Added after on bottom");
+ adapter.notifyDataSetChanged();
+
+ // should call onBottomComplete function of DropDownListView at end of on bottom complete.
+ listView.onBottomComplete();
+ }
+
+ super.onPostExecute(result);
+ }
+ }
+}
diff --git a/src/cn/trinea/android/demo/MyAIDLInterface.aidl b/src/cn/trinea/android/demo/MyAIDLInterface.aidl
new file mode 100644
index 0000000..00cfa55
--- /dev/null
+++ b/src/cn/trinea/android/demo/MyAIDLInterface.aidl
@@ -0,0 +1,11 @@
+package cn.trinea.android.demo;
+
+/**
+ * @author Trinea 2012-9-25
+ */
+interface MyAIDLInterface {
+
+ int getCount();
+
+ void setCount(int count);
+}
diff --git a/src/cn/trinea/android/demo/MyAIDLService.java b/src/cn/trinea/android/demo/MyAIDLService.java
new file mode 100644
index 0000000..78a8276
--- /dev/null
+++ b/src/cn/trinea/android/demo/MyAIDLService.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2012 Trinea.cn All right reserved. This software is the
+ * confidential and proprietary information of Trinea.cn ("Confidential
+ * Information"). You shall not disclose such Confidential Information and shall
+ * use it only in accordance with the terms of the license agreement you entered
+ * into with Trinea.cn.
+ */
+package cn.trinea.android.demo;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.widget.Toast;
+
+/**
+ * MyAIDLService
+ *
+ * @author Trinea 2013-5-9
+ */
+public class MyAIDLService extends Service {
+
+ private int mCount;
+ private MyAIDLInterface.Stub myBinder = new MyAIDLInterface.Stub() {
+
+ @Override
+ public void setCount(int count) throws RemoteException {
+ mCount = count;
+ }
+
+ @Override
+ public int getCount() throws RemoteException {
+ return mCount;
+ }
+ };
+
+ @Override
+ public void onCreate() {
+ mCount = 0;
+ Toast.makeText(this, "Service onCreate", Toast.LENGTH_SHORT).show();
+ super.onCreate();
+ }
+
+ @Override
+ public void onDestroy() {
+ Toast.makeText(this, "Service onDestroy", Toast.LENGTH_SHORT).show();
+ super.onDestroy();
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ Toast.makeText(this, Integer.toString(mCount), Toast.LENGTH_SHORT).show();
+ return super.onStartCommand(intent, flags, startId);
+ }
+
+ public int getCount() {
+ return mCount;
+ }
+
+ /**
+ * 服务被绑定时调用 返回值用于让调用者和服务通信,传入ServiceConnection的public void onServiceConnected(ComponentName name, IBinder
+ * service)函数第二个参数
+ */
+ @Override
+ public IBinder onBind(Intent intent) {
+ return myBinder;
+ }
+}
diff --git a/src/cn/trinea/android/demo/MyIntentService.java b/src/cn/trinea/android/demo/MyIntentService.java
new file mode 100644
index 0000000..3f2821e
--- /dev/null
+++ b/src/cn/trinea/android/demo/MyIntentService.java
@@ -0,0 +1,28 @@
+package cn.trinea.android.demo;
+
+import android.app.IntentService;
+import android.content.Intent;
+
+/**
+ * MyIntentService
+ *
+ * @author Trinea 2013-5-9
+ */
+public class MyIntentService extends IntentService {
+
+ public MyIntentService(){
+ super("MyIntentService");
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ try {
+ System.out.println("IntentService1 Begin Sleep. " + "Thread name: " + Thread.currentThread().getName()
+ + ", Thread Id: " + Thread.currentThread().getId());
+ Thread.sleep(3000);
+ System.out.println("IntentService1 End. ");
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/cn/trinea/android/demo/MyService.java b/src/cn/trinea/android/demo/MyService.java
new file mode 100644
index 0000000..36f997d
--- /dev/null
+++ b/src/cn/trinea/android/demo/MyService.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2012 Trinea.cn All right reserved. This software is the
+ * confidential and proprietary information of Trinea.cn ("Confidential
+ * Information"). You shall not disclose such Confidential Information and shall
+ * use it only in accordance with the terms of the license agreement you entered
+ * into with Trinea.cn.
+ */
+package cn.trinea.android.demo;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.widget.Toast;
+
+/**
+ * MyService
+ *
+ * @author Trinea 2013-5-9
+ */
+public class MyService extends Service {
+
+ private int count;
+ private MyBinder myBinder = new MyBinder();
+
+ @Override
+ public void onCreate() {
+ Toast.makeText(this, "Service onCreate", Toast.LENGTH_SHORT).show();
+ count = 0;
+ super.onCreate();
+ }
+
+ @Override
+ public void onDestroy() {
+ Toast.makeText(this, "Service onDestroy", Toast.LENGTH_SHORT).show();
+ super.onDestroy();
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ return super.onStartCommand(intent, flags, startId);
+ }
+
+ /**
+ * 服务被绑定时调用 返回值用于让调用者和服务通信,传入ServiceConnection的public void onServiceConnected(ComponentName name, IBinder
+ * service)函数第二个参数
+ */
+ @Override
+ public IBinder onBind(Intent intent) {
+ Toast.makeText(this, "Service onBind", Toast.LENGTH_SHORT).show();
+ return myBinder;
+ }
+
+ public boolean onUnbind(Intent intent) {
+ Toast.makeText(this, "Service onUnbind", Toast.LENGTH_SHORT).show();
+ return false;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public int increaseCount() {
+ return ++count;
+ }
+
+ public int decreaseCount() {
+ return --count;
+ }
+
+ public class MyBinder extends Binder {
+
+ MyService getService() {
+ return MyService.this;
+ }
+ }
+}
diff --git a/src/cn/trinea/android/demo/PreferencesUtils.java b/src/cn/trinea/android/demo/PreferencesUtils.java
new file mode 100644
index 0000000..48d52a0
--- /dev/null
+++ b/src/cn/trinea/android/demo/PreferencesUtils.java
@@ -0,0 +1,41 @@
+package cn.trinea.android.demo;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+/**
+ * PreferencesUtils
+ *
+ * @author Trinea 2013-5-9
+ */
+public class PreferencesUtils {
+
+ public static final String PREFERENCES_NAME = "TrineaAndroidCommon";
+ public static final String KEY_NAME_DOWNLOAD_ID = "downloadId";
+
+ /**
+ * put long preferences
+ *
+ * @param context
+ * @param key
+ * @param value
+ */
+ public static void putLongPreferences(Context context, String key, long value) {
+ SharedPreferences settings = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = settings.edit();
+ editor.putLong(key, value);
+ editor.commit();
+ }
+
+ /**
+ * get long preferences
+ *
+ * @param context
+ * @param key
+ * @return
+ */
+ public static long getLongPreferences(Context context, String key) {
+ SharedPreferences settings = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
+ return settings.getLong(key, -1);
+ }
+}
diff --git a/src/cn/trinea/android/demo/SearchViewDemo.java b/src/cn/trinea/android/demo/SearchViewDemo.java
new file mode 100644
index 0000000..77252a1
--- /dev/null
+++ b/src/cn/trinea/android/demo/SearchViewDemo.java
@@ -0,0 +1,155 @@
+package cn.trinea.android.demo;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import android.app.ActionBar;
+import android.app.ActionBar.LayoutParams;
+import android.content.Context;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.SearchView;
+import android.widget.SearchView.OnCloseListener;
+import android.widget.TextView;
+
+/**
+ * SearchViewDemo
+ *
+ * @author Trinea 2013-5-9
+ */
+public class SearchViewDemo extends BaseActivity {
+
+ private SearchView searchView;
+ private MyHandler handler;
+
+ // schedule executor
+ private ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(10);
+ private String currentSearchTip;
+
+ private TextView searchInfo;
+
+ private InputMethodManager inputMethodManager;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState, R.layout.search_view_demo);
+
+ inputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
+ handler = new MyHandler();
+ searchInfo = (TextView)findViewById(R.id.searchInfo);
+
+ // set title style
+ ActionBar bar = getActionBar();
+ bar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_HOME_AS_UP
+ | ActionBar.DISPLAY_SHOW_CUSTOM);
+ setTitle(" ");
+ LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View customActionBarView = inflater.inflate(R.layout.search_view_demo_title, null);
+
+ searchView = (SearchView)customActionBarView.findViewById(R.id.search_view);
+ searchView.setVisibility(View.VISIBLE);
+ searchView.setIconifiedByDefault(true);
+ searchView.setIconified(false);
+ if (Build.VERSION.SDK_INT >= 14) {
+ // when edittest is empty, don't show cancal button
+ searchView.onActionViewExpanded();
+ }
+ searchView.setOnCloseListener(new OnCloseListener() {
+
+ @Override
+ public boolean onClose() {
+ // to avoid click x button and the edittext hidden
+ return true;
+ }
+ });
+ searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
+
+ public boolean onQueryTextSubmit(String query) {
+ searchInfo.setText("search submit result");
+ hideSoftInput();
+ return true;
+ }
+
+ public boolean onQueryTextChange(String newText) {
+ if (newText != null && newText.length() > 0) {
+ currentSearchTip = newText;
+ showSearchTip(newText);
+ }
+ return true;
+ }
+ });
+ Display display = getWindowManager().getDefaultDisplay();
+ LayoutParams params = new LayoutParams(display.getWidth()
+ - getResources().getDimensionPixelSize(R.dimen.search_view_margin_left),
+ LayoutParams.WRAP_CONTENT, Gravity.CENTER_VERTICAL | Gravity.RIGHT);
+ bar.setCustomView(customActionBarView, params);
+
+ // show keyboard
+ getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
+ | WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+ }
+
+ public void showSearchTip(String newText) {
+ // excute after 500ms, and when excute, judge current search tip and newText
+ schedule(new SearchTipThread(newText), 500);
+ }
+
+ class SearchTipThread implements Runnable {
+
+ String newText;
+
+ public SearchTipThread(String newText){
+ this.newText = newText;
+ }
+
+ public void run() {
+ // keep only one thread to load current search tip, u can get data from network here
+ if (newText != null && newText.equals(currentSearchTip)) {
+ handler.sendMessage(handler.obtainMessage(1, newText + " search tip"));
+ }
+ }
+ }
+
+ public ScheduledFuture> schedule(Runnable command, long delayTimeMills) {
+ return scheduledExecutor.schedule(command, delayTimeMills, TimeUnit.MILLISECONDS);
+ }
+
+ private class MyHandler extends Handler {
+
+ @Override
+ public void handleMessage(Message msg) {
+
+ switch (msg.what) {
+ case 1:
+ searchInfo.setText((String)msg.obj);
+ break;
+ }
+ }
+ }
+
+ /**
+ * hide soft input
+ */
+ private void hideSoftInput() {
+ if (inputMethodManager != null) {
+ View v = SearchViewDemo.this.getCurrentFocus();
+ if (v == null) {
+ return;
+ }
+
+ inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
+ searchView.clearFocus();
+ }
+ }
+
+}
diff --git a/src/cn/trinea/android/demo/ServiceDemo.java b/src/cn/trinea/android/demo/ServiceDemo.java
new file mode 100644
index 0000000..33c705b
--- /dev/null
+++ b/src/cn/trinea/android/demo/ServiceDemo.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2012 Trinea.cn All right reserved. This software is the
+ * confidential and proprietary information of Trinea.cn ("Confidential
+ * Information"). You shall not disclose such Confidential Information and shall
+ * use it only in accordance with the terms of the license agreement you entered
+ * into with Trinea.cn.
+ */
+package cn.trinea.android.demo;
+
+import android.app.ActionBar;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.Toast;
+import cn.trinea.android.demo.MyService.MyBinder;
+
+/**
+ * ServiceDemo,包括start普通服务、绑定普通服务、Intent Service
+ *
+ * @author Trinea 2013-5-9
+ */
+public class ServiceDemo extends BaseActivity {
+
+ private MyService myService;
+ private Intent myServiceIntent;
+ private Intent myAIDLServiceIntent;
+ private Intent myIntentServiceIntent;
+ private Intent myIntentService2Intent;
+
+ private Button startServiceBtn;
+ private Button stopServiceBtn;
+ private Button startIntentServiceBtn;
+
+ private Button boundServiceBtn;
+ private Button operateBoundServiceBtn;
+ private Button getBoundServiceProBtn;
+ private Button unboundServiceBtn;
+
+ private Button startAIDLServiceBtn;
+ private Button stopAIDLServiceBtn;
+
+ private ServiceConnection con = new ServiceConnection() {
+
+ /**
+ * 服务所在进程被kill或是crash时系统调用,而不是unbindService时调用
+ */
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ Toast.makeText(getApplicationContext(), "Service disconnect",
+ Toast.LENGTH_SHORT).show();
+ }
+
+ /**
+ * 服务连接时调用,若已经连接不进行调用
+ */
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ myService = ((MyBinder)service).getService();
+ Toast.makeText(getApplicationContext(), "Service Connect", Toast.LENGTH_SHORT)
+ .show();
+ }
+ };
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState, R.layout.service_demo);
+
+ ActionBar bar = getActionBar();
+ bar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_HOME_AS_UP);
+
+ myServiceIntent = new Intent(this, MyService.class);
+ myAIDLServiceIntent = new Intent(ServiceDemo.this, MyAIDLService.class);
+ myIntentServiceIntent = new Intent(ServiceDemo.this, MyIntentService.class);
+ myIntentService2Intent = new Intent(ServiceDemo.this, MyIntentService.class);
+
+ startServiceBtn = (Button)findViewById(R.id.startGeneralService);
+ startServiceBtn.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ startService(myServiceIntent);
+ }
+ });
+
+ stopServiceBtn = (Button)findViewById(R.id.stopGeneralService);
+ stopServiceBtn.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ stopService(myServiceIntent);
+ }
+ });
+
+ startIntentServiceBtn = (Button)findViewById(R.id.startIntentService);
+ startIntentServiceBtn.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ startService(myIntentServiceIntent);
+ startService(myIntentService2Intent);
+ }
+ });
+
+ boundServiceBtn = (Button)findViewById(R.id.boundService);
+ boundServiceBtn.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ bindService(myServiceIntent, con, Context.BIND_AUTO_CREATE);
+ }
+ });
+
+ operateBoundServiceBtn = (Button)findViewById(R.id.operateBoundService);
+ operateBoundServiceBtn.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ if (myService != null) {
+ Toast.makeText(getApplicationContext(), "增加成功,当前值为:" + myService.increaseCount(),
+ Toast.LENGTH_SHORT).show();
+ } else {
+ Toast.makeText(getApplicationContext(), "请先绑定服务。", Toast.LENGTH_SHORT).show();
+ }
+ }
+ });
+
+ getBoundServiceProBtn = (Button)findViewById(R.id.getBoundServicePro);
+ getBoundServiceProBtn.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ if (myService != null) {
+ Toast.makeText(getApplicationContext(), "Service count:" + myService.getCount(), Toast.LENGTH_SHORT)
+ .show();
+ } else {
+ Toast.makeText(getApplicationContext(), "请先绑定服务。", Toast.LENGTH_SHORT).show();
+ }
+ }
+ });
+
+ unboundServiceBtn = (Button)findViewById(R.id.unboundService);
+ unboundServiceBtn.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ if (myService != null) {
+ unbindService(con);
+ myService = null;
+ }
+ }
+ });
+
+ startAIDLServiceBtn = (Button)findViewById(R.id.startAIDLService);
+ startAIDLServiceBtn.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ startService(myAIDLServiceIntent);
+ }
+ });
+
+ stopAIDLServiceBtn = (Button)findViewById(R.id.stopAIDLService);
+ stopAIDLServiceBtn.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ stopService(myAIDLServiceIntent);
+ }
+ });
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ }
+}
diff --git a/src/cn/trinea/android/demo/SlideOnePageGalleryDemo.java b/src/cn/trinea/android/demo/SlideOnePageGalleryDemo.java
new file mode 100644
index 0000000..a0ebcf6
--- /dev/null
+++ b/src/cn/trinea/android/demo/SlideOnePageGalleryDemo.java
@@ -0,0 +1,59 @@
+package cn.trinea.android.demo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.Toast;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemSelectedListener;
+import cn.trinea.android.common.view.SlideOnePageGallery;
+import cn.trinea.android.demo.adapter.ImageListAdapter;
+
+/**
+ * SlideOnePageGalleryDemo
+ *
+ * @author Trinea 2013-5-9
+ */
+public class SlideOnePageGalleryDemo extends BaseActivity {
+
+ private Context context;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState, R.layout.slide_one_page_gallery_demo);
+
+ context = getApplicationContext();
+ SlideOnePageGallery imageGallery = (SlideOnePageGallery)findViewById(R.id.app_app_image_gallery);
+ imageGallery.setOnItemClickListener(new OnItemClickListener() {
+
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ }
+ });
+
+ imageGallery.setOnItemSelectedListener(new OnItemSelectedListener() {
+
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ // Toast.makeText(context, Integer.toString(position), Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+
+ }
+ });
+
+ ImageListAdapter adapter = new ImageListAdapter(getApplicationContext());
+ List idList = new ArrayList();
+ idList.add(R.drawable.image1);
+ idList.add(R.drawable.image2);
+ idList.add(R.drawable.image3);
+ adapter.setImageList(idList);
+ imageGallery.setAdapter(adapter);
+ }
+}
diff --git a/src/cn/trinea/android/demo/ViewPagerDemo.java b/src/cn/trinea/android/demo/ViewPagerDemo.java
new file mode 100644
index 0000000..f51e3be
--- /dev/null
+++ b/src/cn/trinea/android/demo/ViewPagerDemo.java
@@ -0,0 +1,105 @@
+package cn.trinea.android.demo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.app.ActionBar;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentPagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.view.MenuItem;
+import android.widget.Button;
+import cn.trinea.android.demo.utils.AppUtils;
+
+/**
+ * ViewPager和Fragment混合使用的Demo
+ *
+ * @author Trinea 2012-11-14
+ */
+public class ViewPagerDemo extends FragmentActivity {
+
+ List fragmentList = new ArrayList();
+ List titleList = new ArrayList();
+
+ private Button trineaInfoTv;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.view_pager_demo);
+
+ AppUtils.initTrineaInfo(this, trineaInfoTv, getClass());
+
+ ViewPager vp = (ViewPager)findViewById(R.id.view_pager);
+
+ for (int i = 0; i < 3; i++) {
+ ViewPagerFragment viewPagerFragment1 = new ViewPagerFragment();
+ Bundle bundle = new Bundle();
+ bundle.putInt("upImageId", 0);
+ bundle.putString("text", "页面" + i);
+ viewPagerFragment1.setArguments(bundle);
+ titleList.add("title " + i);
+ fragmentList.add(viewPagerFragment1);
+ }
+
+ vp.setAdapter(new myPagerAdapter(getSupportFragmentManager(), fragmentList, titleList));
+
+ ActionBar bar = getActionBar();
+ bar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_HOME_AS_UP);
+ }
+
+ /**
+ * 定义适配器
+ *
+ * @author Trinea 2012-11-15
+ */
+ class myPagerAdapter extends FragmentPagerAdapter {
+
+ private List fragmentList;
+ private List titleList;
+
+ public myPagerAdapter(FragmentManager fm, List fragmentList, List titleList){
+ super(fm);
+ this.fragmentList = fragmentList;
+ this.titleList = titleList;
+ }
+
+ /**
+ * 得到每个页面
+ */
+ @Override
+ public Fragment getItem(int arg0) {
+ return (fragmentList == null || fragmentList.size() == 0) ? null : fragmentList.get(arg0);
+ }
+
+ /**
+ * 每个页面的title
+ */
+ @Override
+ public CharSequence getPageTitle(int position) {
+ return (titleList.size() > position) ? titleList.get(position) : "";
+ }
+
+ /**
+ * 页面的总个数
+ */
+ @Override
+ public int getCount() {
+ return fragmentList == null ? 0 : fragmentList.size();
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home: {
+ onBackPressed();
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/cn/trinea/android/demo/ViewPagerFragment.java b/src/cn/trinea/android/demo/ViewPagerFragment.java
new file mode 100644
index 0000000..7ce739e
--- /dev/null
+++ b/src/cn/trinea/android/demo/ViewPagerFragment.java
@@ -0,0 +1,42 @@
+package cn.trinea.android.demo;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+/**
+ * 定义自己的Fragment,内容为TextView
+ *
+ * @author Trinea 2012-11-15
+ */
+public class ViewPagerFragment extends Fragment {
+
+ public ViewPagerFragment(){
+ super();
+ }
+
+ /**
+ * 覆盖此函数,先通过inflater inflate函数得到view最后返回
+ */
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View v = inflater.inflate(R.layout.view_pager_fragment_demo1, container, false);
+ TextView tv = (TextView)v.findViewById(R.id.viewPagerText);
+ ImageView image = (ImageView)v.findViewById(R.id.viewPagerImage);
+
+ Bundle bundle = getArguments();
+ if (bundle != null) {
+ int upImageId = bundle.getInt("upImageId");
+ if (upImageId != 0) {
+ image.setImageResource(upImageId);
+ }
+ String text = bundle.getString("text");
+ tv.setText(text);
+ }
+ return v;
+ }
+}
diff --git a/src/cn/trinea/android/demo/ViewPagerMulTiFragmentDemo.java b/src/cn/trinea/android/demo/ViewPagerMulTiFragmentDemo.java
new file mode 100644
index 0000000..4575799
--- /dev/null
+++ b/src/cn/trinea/android/demo/ViewPagerMulTiFragmentDemo.java
@@ -0,0 +1,108 @@
+package cn.trinea.android.demo;
+
+import android.app.ActionBar;
+import android.os.Bundle;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.support.v4.view.ViewPager.OnPageChangeListener;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnTouchListener;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+/**
+ * ViewPager实现画廊效果
+ *
+ * @author Trinea 2013-04-03
+ */
+public class ViewPagerMulTiFragmentDemo extends BaseActivity {
+
+ private static int TOTAL_COUNT = 3;
+
+ private RelativeLayout viewPagerContainer;
+ private ViewPager viewPager;
+ private TextView indexText;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState, R.layout.view_pager_multi_fragment_demo);
+
+ viewPager = (ViewPager)findViewById(R.id.view_pager);
+ indexText = (TextView)findViewById(R.id.view_pager_index);
+ viewPagerContainer = (RelativeLayout)findViewById(R.id.pager_layout);
+ viewPager.setAdapter(new MyPagerAdapter());
+ // to cache all page, or we will see the right item delayed
+ viewPager.setOffscreenPageLimit(TOTAL_COUNT);
+ viewPager.setPageMargin(getResources().getDimensionPixelSize(R.dimen.page_margin));
+ MyOnPageChangeListener myOnPageChangeListener = new MyOnPageChangeListener();
+ viewPager.setOnPageChangeListener(myOnPageChangeListener);
+
+ viewPagerContainer.setOnTouchListener(new OnTouchListener() {
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ // dispatch the events to the ViewPager, to solve the problem that we can swipe only the middle view.
+ return viewPager.dispatchTouchEvent(event);
+ }
+ });
+ indexText.setText(new StringBuilder().append("1/").append(TOTAL_COUNT));
+
+ ActionBar bar = getActionBar();
+ bar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_HOME_AS_UP);
+ }
+
+ /**
+ * this is a example fragment, just a imageview, u can replace it with your needs
+ *
+ * @author Trinea 2013-04-03
+ */
+ class MyPagerAdapter extends PagerAdapter {
+
+ @Override
+ public int getCount() {
+ return TOTAL_COUNT;
+ }
+
+ @Override
+ public boolean isViewFromObject(View view, Object object) {
+ return (view == object);
+ }
+
+ @Override
+ public Object instantiateItem(ViewGroup container, int position) {
+ ImageView imageView = new ImageView(ViewPagerMulTiFragmentDemo.this);
+ imageView.setImageResource(R.drawable.image1 + position);
+ ((ViewPager)container).addView(imageView, position);
+ return imageView;
+
+ }
+
+ @Override
+ public void destroyItem(ViewGroup container, int position, Object object) {
+ ((ViewPager)container).removeView((ImageView)object);
+ }
+ }
+
+ public class MyOnPageChangeListener implements OnPageChangeListener {
+
+ @Override
+ public void onPageSelected(int position) {
+ indexText.setText(new StringBuilder().append(position + 1).append("/").append(TOTAL_COUNT));
+ }
+
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ // to refresh frameLayout
+ if (viewPagerContainer != null) {
+ viewPagerContainer.invalidate();
+ }
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int arg0) {
+ }
+ }
+}
diff --git a/src/cn/trinea/android/demo/adapter/ImageListAdapter.java b/src/cn/trinea/android/demo/adapter/ImageListAdapter.java
new file mode 100644
index 0000000..9b50aa4
--- /dev/null
+++ b/src/cn/trinea/android/demo/adapter/ImageListAdapter.java
@@ -0,0 +1,80 @@
+package cn.trinea.android.demo.adapter;
+
+import java.util.List;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+
+import cn.trinea.android.demo.R;
+
+/**
+ * image list adapter
+ *
+ * @author Trinea 2012-11-22
+ */
+public class ImageListAdapter extends BaseAdapter {
+
+ private LayoutInflater inflater;
+ public List imageResIdList;
+
+ public ImageListAdapter(Context context){
+ super();
+ inflater = LayoutInflater.from(context);
+ }
+
+ @Override
+ public int getCount() {
+ return isEmpty(imageResIdList) ? 0 : imageResIdList.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return isEmpty(imageResIdList) ? null : imageResIdList.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder holder;
+ if (convertView == null) {
+ convertView = inflater.inflate(R.layout.image_list_item, null);
+ holder = new ViewHolder();
+ holder.imageView = (ImageView)convertView.findViewById(R.id.image_list_image);
+ convertView.setTag(holder);
+ } else {
+ holder = (ViewHolder)convertView.getTag();
+ }
+ holder.imageView.setImageResource(imageResIdList.get(position));
+ return convertView;
+ }
+
+ public List getImageList() {
+ return imageResIdList;
+ }
+
+ public void setImageList(List imageList) {
+ this.imageResIdList = imageList;
+ }
+
+ /**
+ * ViewHolder
+ *
+ * @author Trinea 2012-11-22
+ */
+ static class ViewHolder {
+
+ ImageView imageView;
+ }
+
+ private boolean isEmpty(List imageList) {
+ return imageList == null || imageList.size() == 0;
+ }
+}
diff --git a/src/cn/trinea/android/demo/utils/AppUtils.java b/src/cn/trinea/android/demo/utils/AppUtils.java
new file mode 100644
index 0000000..ccf201f
--- /dev/null
+++ b/src/cn/trinea/android/demo/utils/AppUtils.java
@@ -0,0 +1,91 @@
+package cn.trinea.android.demo.utils;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.net.Uri;
+import android.text.Html;
+import android.text.Spanned;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import cn.trinea.android.demo.BorderScrollViewDemo;
+import cn.trinea.android.demo.BroadcastReceiverDemo;
+import cn.trinea.android.demo.DownloadManagerDemo;
+import cn.trinea.android.demo.DropDownListViewDemo;
+import cn.trinea.android.demo.R;
+import cn.trinea.android.demo.SearchViewDemo;
+import cn.trinea.android.demo.ServiceDemo;
+import cn.trinea.android.demo.SlideOnePageGalleryDemo;
+import cn.trinea.android.demo.ViewPagerDemo;
+import cn.trinea.android.demo.ViewPagerMulTiFragmentDemo;
+
+/**
+ * AppUtils
+ *
+ * @author Trinea 2013-5-9
+ */
+public class AppUtils {
+
+ public static String PROFILE = "个人主页: ";
+ public static String ABOUT = "相关介绍见: ";
+
+ public static void initTrineaInfo(final Activity activity, Button trineaInfoTv, Class sourClass) {
+ trineaInfoTv = (Button)activity.findViewById(R.id.trineaInfo);
+ final String[] result = getText(sourClass);
+ Spanned text = Html.fromHtml(result[1]);
+ trineaInfoTv.setText(text);
+ trineaInfoTv.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ Uri web = Uri.parse(result[0]);
+ Intent i = new Intent(Intent.ACTION_VIEW, web);
+ i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ activity.startActivity(i);
+ }
+ });
+ }
+
+ public static String[] getText(Class sourClass) {
+ String prefix = null, url = null, name = null;
+ if (sourClass == SearchViewDemo.class) {
+ url = "http://www.trinea.cn/android/android-searchview%E4%BB%8B%E7%BB%8D%E5%8F%8A%E6%90%9C%E7%B4%A2%E6%8F%90%E7%A4%BA%E5%AE%9E%E7%8E%B0/";
+ name = "SearchView介绍及搜索提示实现";
+ } else if (sourClass == ViewPagerMulTiFragmentDemo.class) {
+ url = "http://www.trinea.cn/android/viewpager%E5%AE%9E%E7%8E%B0%E7%94%BB%E5%BB%8A%E4%B8%80%E5%B1%8F%E5%A4%9A%E4%B8%AAfragment%E6%95%88%E6%9E%9C/";
+ name = "viewpager实现画廊效果";
+ } else if (sourClass == DownloadManagerDemo.class) {
+ url = "http://www.trinea.cn/android/android系统下载管理downloadmanager功能介绍及使用示例";
+ name = "系统下载管理使用";
+ } else if (sourClass == SlideOnePageGalleryDemo.class) {
+ url = "http://www.trinea.cn/android/gallery滑动一页一个item效果/";
+ name = "Gallery滑动一页(一个Item)效果";
+ } else if (sourClass == ViewPagerDemo.class) {
+ url = "http://www.cnblogs.com/trinea/archive/2012/11/23/2771273.html";
+ name = "ViewPager、Fragment使用";
+ } else if (sourClass == ServiceDemo.class) {
+ url = "http://www.cnblogs.com/trinea/archive/2012/11/08/2699856.html";
+ name = "Service介绍";
+ } else if (sourClass == BroadcastReceiverDemo.class) {
+ url = "http://www.cnblogs.com/trinea/archive/2012/11/09/2763182.html";
+ name = "BroadcastReceiver介绍";
+ } else if (sourClass == BorderScrollViewDemo.class) {
+ url = "http://www.trinea.cn/?p=445";
+ name = "BorderScrollViewDemo介绍";
+ } else if (sourClass == DropDownListViewDemo.class) {
+ url = "http://www.trinea.cn/?p=523";
+ name = "下拉刷新及底部加载更多Listview";
+ } else {
+ prefix = "个人主页:";
+ url = "http://www.trinea.cn";
+ name = " Trinea";
+ }
+ String[] result = new String[] { url, getUrlInfo(prefix, url, name) };
+ return result;
+ }
+
+ private static String getUrlInfo(String prefix, String url, String name) {
+ return new StringBuilder().append(prefix == null ? ABOUT : prefix).append("").append(name).append("").toString();
+ }
+}
diff --git a/src/cn/trinea/android/demo/utils/DownloadManagerPro.java b/src/cn/trinea/android/demo/utils/DownloadManagerPro.java
new file mode 100644
index 0000000..0d5bf3b
--- /dev/null
+++ b/src/cn/trinea/android/demo/utils/DownloadManagerPro.java
@@ -0,0 +1,186 @@
+package cn.trinea.android.demo.utils;
+
+import android.app.DownloadManager;
+import android.database.Cursor;
+import android.net.Uri;
+
+/**
+ * DownloadManagerPro
+ *
+ * @author Trinea 2013-5-4
+ */
+public class DownloadManagerPro {
+
+ public static final Uri CONTENT_URI = Uri.parse("content://downloads/my_downloads");
+
+ private DownloadManager downloadManager;
+
+ public DownloadManagerPro(DownloadManager downloadManager){
+ this.downloadManager = downloadManager;
+ }
+
+ /**
+ * get download status
+ *
+ * @param downloadId
+ * @return
+ */
+ public int getStatusById(long downloadId) {
+ return getInt(downloadId, DownloadManager.COLUMN_STATUS);
+ }
+
+ /**
+ * get downloaded byte, total byte
+ *
+ * @param downloadId
+ * @return a int array with two elements
+ *
+ *
result[0] represents downloaded bytes, This will initially be -1.
+ *
result[1] represents total bytes, This will initially be -1.
+ *
+ */
+ public int[] getDownloadBytes(long downloadId) {
+ int[] bytesAndStatus = getBytesAndStatus(downloadId);
+ return new int[] { bytesAndStatus[0], bytesAndStatus[1] };
+ }
+
+ /**
+ * get downloaded byte, total byte and download status
+ *
+ * @param downloadId
+ * @return a int array with three elements
+ *
+ *
result[0] represents downloaded bytes, This will initially be -1.
+ *
result[1] represents total bytes, This will initially be -1.
+ *
result[2] represents download status, This will initially be 0.
if status of downloadId is {@link DownloadManager#STATUS_PAUSED}, return one of
+ * {@link DownloadManager#PAUSED_WAITING_TO_RETRY}
+ * {@link DownloadManager#PAUSED_WAITING_FOR_NETWORK}
+ * {@link DownloadManager#PAUSED_QUEUED_FOR_WIFI}
+ * {@link DownloadManager#PAUSED_UNKNOWN}