詹子聪 5 tahun lalu
melakukan
ec90e1c8ed
88 mengubah file dengan 3416 tambahan dan 0 penghapusan
  1. 9 0
      .gitignore
  2. 19 0
      ThreeLocation.iml
  3. 1 0
      app/.gitignore
  4. 54 0
      app/build.gradle
  5. TEMPAT SAMPAH
      app/jni/arm64-v8a/libBaiduMapSDK_base_v5_2_1.so
  6. TEMPAT SAMPAH
      app/jni/arm64-v8a/libBaiduMapSDK_map_v5_2_1.so
  7. TEMPAT SAMPAH
      app/jni/arm64-v8a/libindoor.so
  8. TEMPAT SAMPAH
      app/jni/arm64-v8a/liblocSDK7b.so
  9. TEMPAT SAMPAH
      app/jni/armeabi-v7a/libBaiduMapSDK_base_v5_2_1.so
  10. TEMPAT SAMPAH
      app/jni/armeabi-v7a/libBaiduMapSDK_map_v5_2_1.so
  11. TEMPAT SAMPAH
      app/jni/armeabi-v7a/libindoor.so
  12. TEMPAT SAMPAH
      app/jni/armeabi-v7a/liblocSDK7b.so
  13. TEMPAT SAMPAH
      app/jni/armeabi/libBaiduMapSDK_base_v5_2_1.so
  14. TEMPAT SAMPAH
      app/jni/armeabi/libBaiduMapSDK_map_v5_2_1.so
  15. TEMPAT SAMPAH
      app/jni/armeabi/libindoor.so
  16. TEMPAT SAMPAH
      app/jni/armeabi/liblocSDK7b.so
  17. TEMPAT SAMPAH
      app/jni/x86/libBaiduMapSDK_base_v5_2_1.so
  18. TEMPAT SAMPAH
      app/jni/x86/libBaiduMapSDK_map_v5_2_1.so
  19. TEMPAT SAMPAH
      app/jni/x86/libindoor.so
  20. TEMPAT SAMPAH
      app/jni/x86/liblocSDK7b.so
  21. TEMPAT SAMPAH
      app/jni/x86_64/libBaiduMapSDK_base_v5_2_1.so
  22. TEMPAT SAMPAH
      app/jni/x86_64/libBaiduMapSDK_map_v5_2_1.so
  23. TEMPAT SAMPAH
      app/jni/x86_64/libindoor.so
  24. TEMPAT SAMPAH
      app/jni/x86_64/liblocSDK7b.so
  25. TEMPAT SAMPAH
      app/libs/BaiduLBS_Android.jar
  26. 24 0
      app/proguard-rules.pro
  27. 26 0
      app/src/androidTest/java/com/itant/dotonmap/ExampleInstrumentedTest.java
  28. 48 0
      app/src/main/AndroidManifest.xml
  29. 456 0
      app/src/main/java/com/itant/dotonmap/MainActivity.java
  30. 26 0
      app/src/main/java/com/itant/dotonmap/MapApplication.java
  31. 169 0
      app/src/main/java/com/itant/dotonmap/SearchActivity.java
  32. 73 0
      app/src/main/java/com/itant/dotonmap/bean/LocationBean.java
  33. 30 0
      app/src/main/java/com/itant/dotonmap/tool/DialogTool.java
  34. 14 0
      app/src/main/res/drawable-v21/ripple_item.xml
  35. 11 0
      app/src/main/res/drawable/ripple_item.xml
  36. 121 0
      app/src/main/res/layout/activity_main.xml
  37. 30 0
      app/src/main/res/layout/activity_search.xml
  38. 31 0
      app/src/main/res/layout/item_search_result.xml
  39. TEMPAT SAMPAH
      app/src/main/res/mipmap-hdpi/ic_launcher.png
  40. TEMPAT SAMPAH
      app/src/main/res/mipmap-hdpi/location.png
  41. TEMPAT SAMPAH
      app/src/main/res/mipmap-hdpi/location_1.png
  42. TEMPAT SAMPAH
      app/src/main/res/mipmap-hdpi/location_2.png
  43. TEMPAT SAMPAH
      app/src/main/res/mipmap-hdpi/location_3.png
  44. TEMPAT SAMPAH
      app/src/main/res/mipmap-mdpi/ic_launcher.png
  45. TEMPAT SAMPAH
      app/src/main/res/mipmap-xhdpi/ic_launcher.png
  46. TEMPAT SAMPAH
      app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  47. TEMPAT SAMPAH
      app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  48. 12 0
      app/src/main/res/values-v19/styles.xml
  49. 14 0
      app/src/main/res/values-v21/styles.xml
  50. 35 0
      app/src/main/res/values/colors.xml
  51. 13 0
      app/src/main/res/values/dimen.xml
  52. 3 0
      app/src/main/res/values/strings.xml
  53. 10 0
      app/src/main/res/values/styles.xml
  54. 17 0
      app/src/test/java/com/itant/dotonmap/ExampleUnitTest.java
  55. 27 0
      build.gradle
  56. 18 0
      gradle.properties
  57. TEMPAT SAMPAH
      gradle/wrapper/gradle-wrapper.jar
  58. 6 0
      gradle/wrapper/gradle-wrapper.properties
  59. 160 0
      gradlew
  60. 90 0
      gradlew.bat
  61. 32 0
      library/build.gradle
  62. 17 0
      library/proguard-rules.pro
  63. 26 0
      library/src/androidTest/java/com/itant/library/ExampleInstrumentedTest.java
  64. 8 0
      library/src/main/AndroidManifest.xml
  65. 8 0
      library/src/main/java/com/itant/library/Placeholder.java
  66. 41 0
      library/src/main/java/com/itant/library/abslistview/CommonAdapter.java
  67. 98 0
      library/src/main/java/com/itant/library/abslistview/MultiItemTypeAdapter.java
  68. 290 0
      library/src/main/java/com/itant/library/abslistview/ViewHolder.java
  69. 20 0
      library/src/main/java/com/itant/library/abslistview/base/ItemViewDelegate.java
  70. 133 0
      library/src/main/java/com/itant/library/abslistview/base/ItemViewDelegateManager.java
  71. 54 0
      library/src/main/java/com/itant/library/recyclerview/CommonAdapter.java
  72. 131 0
      library/src/main/java/com/itant/library/recyclerview/MultiItemTypeAdapter.java
  73. 16 0
      library/src/main/java/com/itant/library/recyclerview/base/ItemViewDelegate.java
  74. 116 0
      library/src/main/java/com/itant/library/recyclerview/base/ItemViewDelegateManager.java
  75. 310 0
      library/src/main/java/com/itant/library/recyclerview/base/ViewHolder.java
  76. 53 0
      library/src/main/java/com/itant/library/recyclerview/utils/WrapperUtils.java
  77. 124 0
      library/src/main/java/com/itant/library/recyclerview/wrapper/EmptyWrapper.java
  78. 149 0
      library/src/main/java/com/itant/library/recyclerview/wrapper/HeaderAndFooterWrapper.java
  79. 159 0
      library/src/main/java/com/itant/library/recyclerview/wrapper/LoadMoreWrapper.java
  80. 13 0
      library/src/main/res/anim/anim_bottom_in.xml
  81. 4 0
      library/src/main/res/values-v21/dimen.xml
  82. 11 0
      library/src/main/res/values/color.xml
  83. 5 0
      library/src/main/res/values/dimen.xml
  84. 3 0
      library/src/main/res/values/strings.xml
  85. 22 0
      library/src/main/res/values/styles.xml
  86. 17 0
      library/src/test/java/com/itant/library/ExampleUnitTest.java
  87. 8 0
      local.properties
  88. 1 0
      settings.gradle

+ 9 - 0
.gitignore

@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild

+ 19 - 0
ThreeLocation.iml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id="ThreeLocation" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="java-gradle" name="Java-Gradle">
+      <configuration>
+        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
+        <option name="BUILDABLE" value="false" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 1 - 0
app/.gitignore

@@ -0,0 +1 @@
+/build

+ 54 - 0
app/build.gradle

@@ -0,0 +1,54 @@
+apply plugin: 'com.android.application'
+
+android {
+    signingConfigs {
+        release {
+            storeFile file('D:\\commonkey')
+            storePassword 'away6899458'
+            keyAlias = 'sz'
+            keyPassword 'away6899458'
+        }
+    }
+    compileSdkVersion 27
+    defaultConfig {
+        applicationId "com.itant.dotonmap"
+        minSdkVersion 14
+        targetSdkVersion 27
+        versionCode 2
+        versionName "1.1"
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        signingConfig signingConfigs.release
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+
+    sourceSets{
+        main{
+            jniLibs.srcDir 'jni'
+            //说明so的路径为该libs路径,关联所有地图SDK的so文件
+        }
+    }
+
+    lintOptions {
+        checkReleaseBuilds false
+        abortOnError false
+    }
+
+}
+
+dependencies {
+    implementation fileTree(include: ['*.jar'], dir: 'libs')
+    implementation 'com.android.support:appcompat-v7:27.1.1'
+    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
+    testImplementation 'junit:junit:4.12'
+    androidTestImplementation 'com.android.support.test:runner:0.5'
+    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+    implementation project(':library')
+
+    compile 'com.umeng.sdk:common:1.5.0'
+    compile 'com.umeng.sdk:analytics:7.5.0'
+}

TEMPAT SAMPAH
app/jni/arm64-v8a/libBaiduMapSDK_base_v5_2_1.so


TEMPAT SAMPAH
app/jni/arm64-v8a/libBaiduMapSDK_map_v5_2_1.so


TEMPAT SAMPAH
app/jni/arm64-v8a/libindoor.so


TEMPAT SAMPAH
app/jni/arm64-v8a/liblocSDK7b.so


TEMPAT SAMPAH
app/jni/armeabi-v7a/libBaiduMapSDK_base_v5_2_1.so


TEMPAT SAMPAH
app/jni/armeabi-v7a/libBaiduMapSDK_map_v5_2_1.so


TEMPAT SAMPAH
app/jni/armeabi-v7a/libindoor.so


TEMPAT SAMPAH
app/jni/armeabi-v7a/liblocSDK7b.so


TEMPAT SAMPAH
app/jni/armeabi/libBaiduMapSDK_base_v5_2_1.so


TEMPAT SAMPAH
app/jni/armeabi/libBaiduMapSDK_map_v5_2_1.so


TEMPAT SAMPAH
app/jni/armeabi/libindoor.so


TEMPAT SAMPAH
app/jni/armeabi/liblocSDK7b.so


TEMPAT SAMPAH
app/jni/x86/libBaiduMapSDK_base_v5_2_1.so


TEMPAT SAMPAH
app/jni/x86/libBaiduMapSDK_map_v5_2_1.so


TEMPAT SAMPAH
app/jni/x86/libindoor.so


TEMPAT SAMPAH
app/jni/x86/liblocSDK7b.so


TEMPAT SAMPAH
app/jni/x86_64/libBaiduMapSDK_base_v5_2_1.so


TEMPAT SAMPAH
app/jni/x86_64/libBaiduMapSDK_map_v5_2_1.so


TEMPAT SAMPAH
app/jni/x86_64/libindoor.so


TEMPAT SAMPAH
app/jni/x86_64/liblocSDK7b.so


TEMPAT SAMPAH
app/libs/BaiduLBS_Android.jar


+ 24 - 0
app/proguard-rules.pro

@@ -0,0 +1,24 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
+-keep class com.baidu.** {*;}
+-keep class mapsdkvi.com.** {*;}
+-dontwarn com.baidu.**

+ 26 - 0
app/src/androidTest/java/com/itant/dotonmap/ExampleInstrumentedTest.java

@@ -0,0 +1,26 @@
+package com.itant.dotonmap;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() throws Exception {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getTargetContext();
+
+        assertEquals("com.itant.dotonmap", appContext.getPackageName());
+    }
+}

+ 48 - 0
app/src/main/AndroidManifest.xml

@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.itant.dotonmap">
+
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
+    <application
+        android:name=".MapApplication"
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:supportsRtl="true"
+        android:theme="@style/AppTheme">
+        <meta-data
+            android:name="com.baidu.lbsapi.API_KEY"
+            android:value="6K1Ynf4w56vPt29Hifns4GYUpqtP8Glp" />
+
+
+        <activity android:name=".MainActivity"
+            android:screenOrientation="portrait"
+            android:configChanges="keyboardHidden|orientation|screenSize">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".SearchActivity"
+            android:screenOrientation="portrait"
+            android:configChanges="keyboardHidden|orientation|screenSize"/>
+
+        <!--如果不加这个service,在只有移动网络的时候,不会成功-->
+        <service
+            android:name="com.baidu.location.f"
+            android:enabled="true"
+            android:process=":remote"/>
+    </application>
+
+</manifest>

+ 456 - 0
app/src/main/java/com/itant/dotonmap/MainActivity.java

@@ -0,0 +1,456 @@
+package com.itant.dotonmap;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.location.LocationManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v4.app.ActivityCompat;
+import android.support.v7.app.AppCompatActivity;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.baidu.location.BDLocation;
+import com.baidu.location.BDLocationListener;
+import com.baidu.location.LocationClient;
+import com.baidu.location.LocationClientOption;
+import com.baidu.mapapi.map.BaiduMap;
+import com.baidu.mapapi.map.BitmapDescriptor;
+import com.baidu.mapapi.map.BitmapDescriptorFactory;
+import com.baidu.mapapi.map.MapStatus;
+import com.baidu.mapapi.map.MapStatusUpdate;
+import com.baidu.mapapi.map.MapStatusUpdateFactory;
+import com.baidu.mapapi.map.MapView;
+import com.baidu.mapapi.map.MarkerOptions;
+import com.baidu.mapapi.map.MyLocationConfiguration;
+import com.baidu.mapapi.map.MyLocationData;
+import com.baidu.mapapi.map.OverlayOptions;
+import com.baidu.mapapi.map.PolylineOptions;
+import com.baidu.mapapi.map.TextOptions;
+import com.baidu.mapapi.model.LatLng;
+import com.baidu.mapapi.model.LatLngBounds;
+import com.baidu.mapapi.utils.DistanceUtil;
+import com.itant.dotonmap.bean.LocationBean;
+import com.itant.dotonmap.tool.DialogTool;
+import com.umeng.analytics.MobclickAgent;
+
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+public class MainActivity extends AppCompatActivity implements View.OnClickListener {
+    private static final int BAIDU_READ_PHONE_STATE = 100;
+
+    public static final String KEY_REQUEST_CODE = "request_code";
+    public static final String KEY_REQUEST_CITY = "request_city";
+    public static final String KEY_SELECTED_LOCATION = "selected_location";
+    public static final int REQUEST_CODE_1 = 1;
+    public static final int REQUEST_CODE_2 = 2;
+    public static final int REQUEST_CODE_3 = 3;
+
+    private MapView mv_main;
+    private BaiduMap mBaiduMap;
+    //LocationClient类是定位SDK的核心类
+    public LocationClient mLocationClient;
+    private BDLocation mLocation;
+    private BDLocationListener mLocationListener;
+
+    private LocationBean mLocationBean1;
+    private LocationBean mLocationBean2;
+    private LocationBean mLocationBean3;
+    private LatLng mCurrentLatLng;
+    private LatLng mPoint1;
+    private LatLng mPoint2;
+    private LatLng mPoint3;
+
+    private TextView tv_1;
+    private TextView tv_2;
+    private TextView tv_3;
+
+    // 保留两位小数
+    private DecimalFormat mFormat = new DecimalFormat("#.00");
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        findViewById(R.id.ll_1).setOnClickListener(this);
+        findViewById(R.id.ll_2).setOnClickListener(this);
+        findViewById(R.id.ll_3).setOnClickListener(this);
+
+        tv_1 = findViewById(R.id.tv_1);
+        tv_2 = findViewById(R.id.tv_2);
+        tv_3 = findViewById(R.id.tv_3);
+
+        boolean isPermissionGranted = isPermissionGranted();
+        if (isPermissionGranted) {
+            initBaiduMap();
+        }
+    }
+
+    private void initBaiduMap() {
+        LocationManager locManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
+        if(!locManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
+            // 未打开位置开关,可能导致定位失败或定位不准,提示用户或做相应处理
+            Toast.makeText(this, "为保证定位准确请打开位置开关", Toast.LENGTH_SHORT).show();
+        }
+
+        //获取地图控件引用
+        mv_main = findViewById(R.id.mv_main);
+        mBaiduMap = mv_main.getMap();
+
+        // 定位开始----------------------->
+        mLocationClient = new LocationClient(getApplicationContext());
+        LocationClientOption option = new LocationClientOption();
+        //打开gps
+        option.setOpenGps(true);
+        //就是这个方法设置为true,才能获取当前的位置信息(当前城市名等信息)
+        option.setIsNeedAddress(true);
+        //设置坐标类型为bd09ll 百度需要的坐标,也可以返回其他type类型,大家可以查看下
+        option.setCoorType("bd09ll");
+        //设置网络优先
+        option.setPriority(LocationClientOption.NetWorkFirst);
+        //定时定位,每隔5秒钟定位一次
+        //option.setScanSpan(5000);
+        mLocationClient.setLocOption(option);
+        mLocationListener = new BDLocationListener() {
+            @Override
+            public void onReceiveLocation(BDLocation bdLocation) {
+                if (bdLocation == null)
+                    return;
+                // 这里可以获取经纬度
+                mLocation = bdLocation;
+                showHere();
+            }
+        };
+        mLocationClient.registerLocationListener(mLocationListener);
+        // 这句代码百度api上给的没有,没有这个代码下面的回调方法不会执行的
+        mLocationClient.start();
+        // 定位结束<-----------------------
+    }
+
+    private boolean isPermissionGranted() {
+        if (Build.VERSION.SDK_INT < 23) {
+            return true;
+        }
+
+        String[] mRequiredPermissions = {Manifest.permission.READ_PHONE_STATE,
+                Manifest.permission.ACCESS_COARSE_LOCATION,
+                Manifest.permission.ACCESS_FINE_LOCATION,
+                Manifest.permission.READ_EXTERNAL_STORAGE,
+                Manifest.permission.WRITE_EXTERNAL_STORAGE};
+
+        boolean permissionGranted = true;
+        for (String permission : mRequiredPermissions) {
+            if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
+                permissionGranted = false;
+                break;
+            }
+        }
+
+        if (permissionGranted) {
+            return true;
+        }
+
+        // 申请一个(或多个)权限,并提供用于回调返回的获取码(用户定义)
+        ActivityCompat.requestPermissions(this, mRequiredPermissions, BAIDU_READ_PHONE_STATE);
+
+        return false;
+    }
+
+    private void showHere() {
+        if (mLocation == null) {
+            return;
+        }
+        // 开启定位图层
+        mBaiduMap.setMyLocationEnabled(true);
+
+        // 构造定位数据
+        MyLocationData locData = new MyLocationData.Builder()
+                //.accuracy(mLocation.getRadius())
+                // 此处设置开发者获取到的方向信息,顺时针0-360
+                //.direction(100)
+                .latitude(mLocation.getLatitude())
+                .longitude(mLocation.getLongitude()).build();
+
+        // 设置定位数据
+        mBaiduMap.setMyLocationData(locData);
+
+        // 设置定位图层的配置(定位模式,是否允许方向信息,用户自定义定位图标)
+        BitmapDescriptor mCurrentMarker = BitmapDescriptorFactory.fromResource(R.mipmap.location);
+        MyLocationConfiguration config = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL, true, mCurrentMarker);
+        mBaiduMap.setMyLocationConfiguration(config);
+
+        // 显示当前位置
+        LatLng ll = new LatLng(mLocation.getLatitude(), mLocation.getLongitude());
+        mCurrentLatLng = ll;
+        MapStatus.Builder builder = new MapStatus.Builder();
+        builder.target(ll).zoom(18.0f);
+        mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
+
+    }
+
+
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        // 在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
+        if (mv_main != null) {
+            mv_main.onPause();
+        }
+
+        MobclickAgent.onPause(this);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        // 在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
+        if (mv_main != null) {
+            mv_main.onResume();
+        }
+
+        MobclickAgent.onResume(this);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        // 在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
+        if (mv_main != null) {
+            mv_main.onDestroy();
+        }
+
+        if (mLocationClient != null && mLocationListener != null) {
+            mLocationClient.unRegisterLocationListener(mLocationListener);
+        }
+    }
+
+
+    @Override
+    public void onClick(View v) {
+
+        if (mLocation == null || TextUtils.isEmpty(mLocation.getCity())) {
+            Toast.makeText(this, "获取当前城市失败", Toast.LENGTH_SHORT).show();
+            return;
+        }
+        switch (v.getId()) {
+
+            case R.id.ll_1:
+                Intent locationIntent1 = new Intent(this, SearchActivity.class);
+                locationIntent1.putExtra(KEY_REQUEST_CODE, REQUEST_CODE_1);
+                locationIntent1.putExtra(KEY_REQUEST_CITY, mLocation.getCity());
+                startActivityForResult(locationIntent1, REQUEST_CODE_1);
+                break;
+            case R.id.ll_2:
+                Intent locationIntent2 = new Intent(this, SearchActivity.class);
+                locationIntent2.putExtra(KEY_REQUEST_CODE, REQUEST_CODE_2);
+                locationIntent2.putExtra(KEY_REQUEST_CITY, mLocation.getCity());
+                startActivityForResult(locationIntent2, REQUEST_CODE_2);
+                break;
+            case R.id.ll_3:
+                Intent locationIntent3 = new Intent(this, SearchActivity.class);
+                locationIntent3.putExtra(KEY_REQUEST_CODE, REQUEST_CODE_3);
+                locationIntent3.putExtra(KEY_REQUEST_CITY, mLocation.getCity());
+                startActivityForResult(locationIntent3, REQUEST_CODE_3);
+                break;
+        }
+    }
+
+    @Override
+    public void onRequestPermissionsResult(int requestCode,String[] permissions, int[] grantResults) {
+        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+
+        for (int grant : grantResults) {
+            if (grant != PackageManager.PERMISSION_GRANTED) {
+                //没有获取到权限,做特殊处理
+                DialogTool.showPermissionDialog(this);
+                return;
+            }
+        }
+
+        //获取到权限,做相应处理
+        //调用定位SDK应确保相关权限均被授权,否则会引起定位失败
+        initBaiduMap();
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        if (resultCode != RESULT_OK) {
+            return;
+        }
+
+        switch (requestCode) {
+            case REQUEST_CODE_1:
+                mLocationBean1 = (LocationBean) data.getSerializableExtra(KEY_SELECTED_LOCATION);
+                tv_1.setText(mLocationBean1.getAddress() + " " + mLocationBean1.getName());
+                break;
+            case REQUEST_CODE_2:
+                mLocationBean2 = (LocationBean) data.getSerializableExtra(KEY_SELECTED_LOCATION);
+                tv_2.setText(mLocationBean2.getAddress() + " " +  mLocationBean2.getName());
+                break;
+            case REQUEST_CODE_3:
+                mLocationBean3 = (LocationBean) data.getSerializableExtra(KEY_SELECTED_LOCATION);
+                tv_3.setText(mLocationBean3.getAddress() + " " + mLocationBean3.getName());
+                break;
+        }
+
+        if (mLocationBean1 != null && mLocationBean2 != null && mLocationBean3 != null) {
+            // 说明3个点都齐全了,可以绘制了。绘制之前,先清除之前的图层和标记。
+
+            if (mBaiduMap == null) {
+                return;
+            }
+
+            // 添加标记
+            setupMark();
+        }
+    }
+
+    private void setupMark() {
+        // 清除标记
+        mBaiduMap.clear();
+
+        //创建OverlayOptions的集合
+        List<OverlayOptions> options = new ArrayList<OverlayOptions>();
+        //设置坐标点
+        LatLng point1 = new LatLng(mLocationBean1.getLat(), mLocationBean1.getLng());
+        LatLng point2 = new LatLng(mLocationBean2.getLat(), mLocationBean2.getLng());
+        LatLng point3 = new LatLng(mLocationBean3.getLat(), mLocationBean3.getLng());
+        mPoint1 = point1;
+        mPoint2 = point2;
+        mPoint3 = point3;
+
+        //创建OverlayOptions属性
+        OverlayOptions option1 =  new MarkerOptions()
+                .position(point1)
+                .icon(BitmapDescriptorFactory.fromResource(R.mipmap.location_1));
+        OverlayOptions option2 =  new MarkerOptions()
+                .position(point2)
+                .icon(BitmapDescriptorFactory.fromResource(R.mipmap.location_2));
+        OverlayOptions option3 =  new MarkerOptions()
+                .position(point3)
+                .icon(BitmapDescriptorFactory.fromResource(R.mipmap.location_3));
+
+        //将OverlayOptions添加到list
+        options.add(option1);
+        options.add(option2);
+        options.add(option3);
+
+        // 1.画线
+        List<LatLng> points = new ArrayList<>();
+        //构建折线点坐标
+        points.add(point1);
+        points.add(point2);
+        points.add(point3);
+        drawLines(points);
+
+        // 2.在地图上批量添加点
+        mBaiduMap.addOverlays(options);
+
+        // 3.计算点之间的距离
+        calculateDistance();
+
+        // 让标注显示在最佳视野内
+        LatLng[] viewPoints = {point1, point2, point3};
+        showWellZoom(viewPoints);
+    }
+
+    private void showWellZoom(LatLng[] points) {
+        LatLngBounds.Builder builder = new LatLngBounds.Builder();
+        for (LatLng p : points) {
+            builder = builder.include(p);
+        }
+        LatLngBounds latlngBounds = builder.build();
+        MapStatusUpdate u = MapStatusUpdateFactory.newLatLngBounds(latlngBounds, mv_main.getWidth(), mv_main.getHeight());
+        mBaiduMap.animateMapStatus(u);
+    }
+
+    private void drawLines(List<LatLng> points) {
+        List<Integer> colors = new ArrayList<>();
+        colors.add(getResources().getColor(R.color.blue_alipay));
+        colors.add(getResources().getColor(R.color.green_pressed));
+        //colors.add(getResources().getColor(R.color.purple));
+        //colors.add(getResources().getColor(R.color.gray_text_s));
+
+        //绘制折线(这样先画连着的,再画开始和结束,分开画,是为了避免颜色错乱,百度地图的bug)
+        OverlayOptions ooPolyline1 = new PolylineOptions()
+                .width(8)
+                .colorsValues(colors)
+                .points(points);
+        mBaiduMap.addOverlay(ooPolyline1);
+
+        List<LatLng> startEndPoints = new ArrayList<>();
+        startEndPoints.add(mPoint1);
+        startEndPoints.add(mPoint3);
+        Integer purpleColor = getResources().getColor(R.color.purple);
+        OverlayOptions ooPolyline2 = new PolylineOptions()
+                .width(8)
+                .color(purpleColor)
+                .points(startEndPoints);
+        mBaiduMap.addOverlay(ooPolyline2);
+    }
+
+    private void calculateDistance() {
+        String p1ToP2 = mFormat.format(DistanceUtil.getDistance(mPoint1, mPoint2)/1000);
+        String p2ToP3 = mFormat.format(DistanceUtil.getDistance(mPoint2, mPoint3)/1000);
+        String p1ToP3 = mFormat.format(DistanceUtil.getDistance(mPoint1, mPoint3)/1000);
+
+        //定义文字所显示的坐标点
+        LatLng llText1 = new LatLng((mPoint1.latitude+mPoint2.latitude)/2, (mPoint1.longitude+mPoint2.longitude)/2);
+        //构建文字Option对象,用于在地图上添加文字
+        OverlayOptions textOption1 = new TextOptions()
+                .bgColor(getResources().getColor(R.color.gray_light_s))
+                .fontSize(34)
+                .fontColor(getResources().getColor(R.color.blue_alipay))
+                .text(p1ToP2+"公里")
+                //.rotate(-30)
+                .position(llText1);
+        //在地图上添加该文字对象并显示
+        mBaiduMap.addOverlay(textOption1);
+
+        //定义文字所显示的坐标点
+        LatLng llText2 = new LatLng((mPoint2.latitude+mPoint3.latitude)/2, (mPoint2.longitude+mPoint3.longitude)/2);
+        //构建文字Option对象,用于在地图上添加文字
+        OverlayOptions textOption2 = new TextOptions()
+                .bgColor(getResources().getColor(R.color.gray_light_s))
+                .fontSize(34)
+                .fontColor(getResources().getColor(R.color.green_pressed))
+                .text(p2ToP3+"公里")
+                //.rotate(-30)
+                .position(llText2);
+        //在地图上添加该文字对象并显示
+        mBaiduMap.addOverlay(textOption2);
+
+        //定义文字所显示的坐标点
+        LatLng llText3 = new LatLng((mPoint1.latitude+mPoint3.latitude)/2, (mPoint1.longitude+mPoint3.longitude)/2);
+        //构建文字Option对象,用于在地图上添加文字
+        OverlayOptions textOption3 = new TextOptions()
+                .bgColor(getResources().getColor(R.color.gray_light_s))
+                .fontSize(34)
+                .fontColor(getResources().getColor(R.color.purple))
+                .text(p1ToP3+"公里")
+                //.rotate(-30)
+                .position(llText3);
+        //在地图上添加该文字对象并显示
+        mBaiduMap.addOverlay(textOption3);
+    }
+
+    private long mLastBackMillis;
+    @Override
+    public void onBackPressed() {
+        if (System.currentTimeMillis() - mLastBackMillis > 2000) {
+            Toast.makeText(this, "再按一次退出", Toast.LENGTH_SHORT).show();
+            mLastBackMillis = System.currentTimeMillis();
+        } else {
+            super.onBackPressed();
+        }
+    }
+}

+ 26 - 0
app/src/main/java/com/itant/dotonmap/MapApplication.java

@@ -0,0 +1,26 @@
+package com.itant.dotonmap;
+
+import android.app.Application;
+
+import com.baidu.mapapi.CoordType;
+import com.baidu.mapapi.SDKInitializer;
+import com.umeng.commonsdk.UMConfigure;
+
+/**
+ * Created by Jason on 2018/10/28.
+ */
+
+public class MapApplication extends Application {
+    @Override
+    public void onCreate() {
+        super.onCreate();
+
+        UMConfigure.init(this, "5bf53e0ef1f556cd6500008c", "all", UMConfigure.DEVICE_TYPE_PHONE, "");
+
+        //在使用SDK各组件之前初始化context信息,传入ApplicationContext
+        SDKInitializer.initialize(this);
+        //自4.3.0起,百度地图SDK所有接口均支持百度坐标和国测局坐标,用此方法设置您使用的坐标类型.
+        //包括BD09LL和GCJ02两种坐标,默认是BD09LL坐标。
+        SDKInitializer.setCoordType(CoordType.BD09LL);
+    }
+}

+ 169 - 0
app/src/main/java/com/itant/dotonmap/SearchActivity.java

@@ -0,0 +1,169 @@
+package com.itant.dotonmap;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.view.View;
+import android.widget.EditText;
+
+import com.baidu.mapapi.search.sug.OnGetSuggestionResultListener;
+import com.baidu.mapapi.search.sug.SuggestionResult;
+import com.baidu.mapapi.search.sug.SuggestionSearch;
+import com.baidu.mapapi.search.sug.SuggestionSearchOption;
+import com.itant.dotonmap.bean.LocationBean;
+import com.itant.library.recyclerview.CommonAdapter;
+import com.itant.library.recyclerview.base.ViewHolder;
+import com.umeng.analytics.MobclickAgent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by Jason on 2018/11/18.
+ */
+
+public class SearchActivity extends AppCompatActivity implements TextWatcher {
+    private EditText et_search;
+    private SuggestionSearch mSuggestionSearch;
+    private String mCity;
+
+    private List<LocationBean> mLocationList;
+    private CommonAdapter<LocationBean> mAdapter;
+    private RecyclerView rv_search;
+
+    private OnGetSuggestionResultListener listener = new OnGetSuggestionResultListener() {
+        public void onGetSuggestionResult(SuggestionResult res) {
+
+            if (res == null || res.getAllSuggestions() == null) {
+                return;
+            }
+
+            List<SuggestionResult.SuggestionInfo> infos = res.getAllSuggestions();
+            mLocationList.clear();
+            for (SuggestionResult.SuggestionInfo info : infos) {
+                if (info.getPt() == null) {
+                    continue;
+                }
+                LocationBean locationBean = new LocationBean();
+                locationBean.setCity(info.getCity());
+                locationBean.setLat(info.getPt().latitude);
+                locationBean.setLate6(info.getPt().latitudeE6);
+                locationBean.setLng(info.getPt().longitude);
+                locationBean.setLnge6(info.getPt().longitudeE6);
+                locationBean.setName(info.getKey());
+                if (!TextUtils.isEmpty(info.getDistrict())) {
+                    locationBean.setAddress(info.getCity() + "-" + info.getDistrict());
+                } else {
+                    locationBean.setAddress(info.getCity());
+                }
+                mLocationList.add(locationBean);
+            }
+
+            mAdapter.notifyDataSetChanged();
+        }
+    };
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_search);
+
+        mSuggestionSearch = SuggestionSearch.newInstance();
+        mSuggestionSearch.setOnGetSuggestionResultListener(listener);
+
+        et_search = findViewById(R.id.et_search);
+        int code = getIntent().getIntExtra(MainActivity.KEY_REQUEST_CODE, 0);
+        mCity = getIntent().getStringExtra(MainActivity.KEY_REQUEST_CITY);
+        switch (code) {
+            case MainActivity.REQUEST_CODE_1:
+                et_search.setHint("请输入位置1");
+                break;
+            case MainActivity.REQUEST_CODE_2:
+                et_search.setHint("请输入位置2");
+                break;
+            case MainActivity.REQUEST_CODE_3:
+                et_search.setHint("请输入位置3");
+                break;
+        }
+
+        et_search.addTextChangedListener(this);
+
+        rv_search = findViewById(R.id.rv_search);
+        final LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
+        rv_search.setLayoutManager(layoutManager);
+        mLocationList = new ArrayList<>();
+        mAdapter = new CommonAdapter<LocationBean>(this, R.layout.item_search_result, mLocationList) {
+            @Override
+            protected void convert(ViewHolder holder, final LocationBean locationBean, int position) {
+                holder.setText(R.id.tv_name, locationBean.getName());
+                holder.setText(R.id.tv_address, locationBean.getAddress());
+                holder.setOnClickListener(R.id.ll_search_result, new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        onResultClick(locationBean);
+                    }
+                });
+            }
+        };
+        rv_search.setAdapter(mAdapter);
+    }
+
+    private void onResultClick(LocationBean locationBean) {
+        Intent intent = getIntent();
+        intent.putExtra(MainActivity.KEY_SELECTED_LOCATION, locationBean);
+        setResult(RESULT_OK, intent);
+        finish();
+    }
+
+    @Override
+    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+    }
+
+    @Override
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+
+    }
+
+    @Override
+    public void afterTextChanged(Editable s) {
+        String keyword = s.toString();
+        if (TextUtils.isEmpty(keyword)) {
+            return;
+        }
+
+        String validKeyword = keyword.replaceAll(" ", "");
+        if (TextUtils.isEmpty(validKeyword)) {
+            return;
+        }
+
+        mSuggestionSearch.requestSuggestion((new SuggestionSearchOption())
+                .keyword(validKeyword)
+                .city(mCity));
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        MobclickAgent.onResume(this);
+    }
+    @Override
+    public void onPause() {
+        super.onPause();
+        MobclickAgent.onPause(this);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        if (mSuggestionSearch != null) {
+            mSuggestionSearch.destroy();
+        }
+    }
+}

+ 73 - 0
app/src/main/java/com/itant/dotonmap/bean/LocationBean.java

@@ -0,0 +1,73 @@
+package com.itant.dotonmap.bean;
+
+import java.io.Serializable;
+
+/**
+ * Created by Jason on 2018/11/18.
+ */
+
+public class LocationBean implements Serializable {
+    private String name;
+    private String city;
+    private String address;
+    private double lat;
+    private double lng;
+    private double late6;
+    private double lnge6;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCity() {
+        return city;
+    }
+
+    public void setCity(String city) {
+        this.city = city;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public double getLat() {
+        return lat;
+    }
+
+    public void setLat(double lat) {
+        this.lat = lat;
+    }
+
+    public double getLng() {
+        return lng;
+    }
+
+    public void setLng(double lng) {
+        this.lng = lng;
+    }
+
+    public double getLate6() {
+        return late6;
+    }
+
+    public void setLate6(double late6) {
+        this.late6 = late6;
+    }
+
+    public double getLnge6() {
+        return lnge6;
+    }
+
+    public void setLnge6(double lnge6) {
+        this.lnge6 = lnge6;
+    }
+}

+ 30 - 0
app/src/main/java/com/itant/dotonmap/tool/DialogTool.java

@@ -0,0 +1,30 @@
+package com.itant.dotonmap.tool;
+
+import android.app.Activity;
+import android.content.DialogInterface;
+import android.support.v7.app.AlertDialog;
+
+/**
+ * Created by Jason on 2018/11/20.
+ */
+
+public class DialogTool {
+    public static void showPermissionDialog(final Activity activity) {
+        // 退出当前账号
+        AlertDialog dialog = new AlertDialog.Builder(activity)
+                //.setIcon(R.mipmap.icon)//设置标题的图片
+                //.setTitle("我是对话框")//设置对话框的标题
+                .setMessage("本应用的正常运行需要定位和存储等权限")//设置对话框的内容
+                //设置对话框的按钮
+                .setPositiveButton("好的", new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        dialog.dismiss();
+                        activity.finish();
+                    }
+                }).create();
+        dialog.setCanceledOnTouchOutside(false);
+        dialog.setCancelable(false);
+        dialog.show();
+    }
+}

+ 14 - 0
app/src/main/res/drawable-v21/ripple_item.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:color="@color/gray_pressed"
+    tools:targetApi="lollipop">
+    <!--上面的是ripple的颜色-->
+
+    <item>
+        <shape android:shape="rectangle">
+            <!--不点击时的颜色-->
+            <solid android:color="@color/white" />
+        </shape>
+    </item>
+</ripple>

+ 11 - 0
app/src/main/res/drawable/ripple_item.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:state_pressed="true">
+        <shape android:shape="rectangle">
+            <solid android:color="@color/gray_pressed" />
+        </shape>
+    </item>
+
+    <item android:drawable="@color/white"></item>
+</selector>

+ 121 - 0
app/src/main/res/layout/activity_main.xml

@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/height_split"
+        android:background="@color/gray_light_s"/>
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:background="@color/white">
+
+        <LinearLayout
+            android:id="@+id/ll_1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:gravity="center_vertical"
+            android:paddingTop="@dimen/margin_s"
+            android:paddingBottom="@dimen/margin_s"
+            android:paddingLeft="@dimen/margin_default"
+            android:paddingRight="@dimen/margin_default"
+            android:background="@drawable/ripple_item">
+            <ImageView
+                android:layout_width="@dimen/width_location"
+                android:layout_height="@dimen/height_location"
+                android:scaleType="fitXY"
+                android:src="@mipmap/location_1"/>
+
+            <TextView
+                android:id="@+id/tv_1"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="@dimen/margin_s"
+                android:text="未选择"
+                android:textSize="@dimen/text_size_p"
+                android:textColor="@color/black_text"/>
+        </LinearLayout>
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/height_split"
+            android:background="@color/gray_light_s"/>
+
+        <LinearLayout
+            android:id="@+id/ll_2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:gravity="center_vertical"
+            android:paddingTop="@dimen/margin_s"
+            android:paddingBottom="@dimen/margin_s"
+            android:paddingLeft="@dimen/margin_default"
+            android:paddingRight="@dimen/margin_default"
+            android:background="@drawable/ripple_item">
+            <ImageView
+                android:layout_width="@dimen/width_location"
+                android:layout_height="@dimen/height_location"
+                android:scaleType="fitXY"
+                android:src="@mipmap/location_2"/>
+
+            <TextView
+                android:id="@+id/tv_2"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="@dimen/margin_s"
+                android:text="未选择"
+                android:textSize="@dimen/text_size_p"
+                android:textColor="@color/black_text"/>
+        </LinearLayout>
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/height_split"
+            android:background="@color/gray_light_s"/>
+
+        <LinearLayout
+            android:id="@+id/ll_3"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:gravity="center_vertical"
+            android:paddingTop="@dimen/margin_s"
+            android:paddingBottom="@dimen/margin_s"
+            android:paddingLeft="@dimen/margin_default"
+            android:paddingRight="@dimen/margin_default"
+            android:background="@drawable/ripple_item">
+            <ImageView
+                android:layout_width="@dimen/width_location"
+                android:layout_height="@dimen/height_location"
+                android:scaleType="fitXY"
+                android:src="@mipmap/location_3"/>
+
+            <TextView
+                android:id="@+id/tv_3"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="@dimen/margin_s"
+                android:text="未选择"
+                android:textSize="@dimen/text_size_p"
+                android:textColor="@color/black_text"/>
+        </LinearLayout>
+    </LinearLayout>
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/height_split"
+        android:background="@color/gray_light_s"/>
+
+    <com.baidu.mapapi.map.MapView
+        android:id="@+id/mv_main"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:clickable="true" />
+
+</LinearLayout>

+ 30 - 0
app/src/main/res/layout/activity_search.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:background="@color/white"
+    android:paddingLeft="@dimen/margin_default"
+    android:paddingRight="@dimen/margin_default">
+
+    <EditText
+        android:id="@+id/et_search"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:minHeight="@dimen/height_search"
+        android:gravity="center_vertical"
+        android:paddingLeft="@dimen/margin_s"
+        android:paddingRight="@dimen/margin_s"
+        android:textSize="@dimen/text_size_sub_title"
+        android:background="@color/transparent"/>
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/height_split"
+        android:background="@color/gray_light_s" />
+
+    <android.support.v7.widget.RecyclerView
+        android:id="@+id/rv_search"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
+</LinearLayout>

+ 31 - 0
app/src/main/res/layout/item_search_result.xml

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:paddingLeft="@dimen/margin_s"
+    android:paddingRight="@dimen/margin_s"
+    android:paddingTop="@dimen/margin_s"
+    android:background="@drawable/ripple_item"
+    android:id="@+id/ll_search_result">
+
+    <TextView
+        android:id="@+id/tv_name"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textSize="@dimen/text_size_sub_title"
+        android:textColor="@color/blue_alipay"/>
+
+    <TextView
+        android:id="@+id/tv_address"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textColor="@color/gray_text"
+        android:layout_marginTop="@dimen/margin_ss"/>
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/height_split"
+        android:background="@color/gray_light_s"
+        android:layout_marginTop="@dimen/margin_s"/>
+</LinearLayout>

TEMPAT SAMPAH
app/src/main/res/mipmap-hdpi/ic_launcher.png


TEMPAT SAMPAH
app/src/main/res/mipmap-hdpi/location.png


TEMPAT SAMPAH
app/src/main/res/mipmap-hdpi/location_1.png


TEMPAT SAMPAH
app/src/main/res/mipmap-hdpi/location_2.png


TEMPAT SAMPAH
app/src/main/res/mipmap-hdpi/location_3.png


TEMPAT SAMPAH
app/src/main/res/mipmap-mdpi/ic_launcher.png


TEMPAT SAMPAH
app/src/main/res/mipmap-xhdpi/ic_launcher.png


TEMPAT SAMPAH
app/src/main/res/mipmap-xxhdpi/ic_launcher.png


TEMPAT SAMPAH
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png


+ 12 - 0
app/src/main/res/values-v19/styles.xml

@@ -0,0 +1,12 @@
+<resources>
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/black</item>
+        <item name="colorPrimaryDark">@color/black</item>
+        <item name="colorAccent">@color/colorAccent</item>
+        <!--导航栏不透明-->
+        <item name="android:windowTranslucentNavigation">false</item>
+    </style>
+
+</resources>

+ 14 - 0
app/src/main/res/values-v21/styles.xml

@@ -0,0 +1,14 @@
+<resources>
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/black</item>
+        <item name="colorPrimaryDark">@color/black</item>
+        <item name="colorAccent">@color/colorAccent</item>
+        <!--导航栏不透明-->
+        <item name="android:windowTranslucentNavigation">false</item>
+        <!--导航栏为黑色-->
+        <item name="android:navigationBarColor">@color/black</item>
+    </style>
+
+</resources>

+ 35 - 0
app/src/main/res/values/colors.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#3F51B5</color>
+    <color name="colorPrimaryDark">#303F9F</color>
+    <color name="colorAccent">#FF4081</color>
+
+    <color name="white">#FFFFFF</color>
+
+    <color name="black">#000000</color>
+    <color name="black_text">#212121</color>
+
+    <color name="gray_disabled">#4DFFFFFF</color>
+    <color name="gray_button">#505160</color>
+    <color name="gray_tab_bg">#666666</color>
+    <color name="gray_light">#F0F0F0</color>
+    <color name="gray_light_s">#E0E0E0</color>
+    <color name="gray_text">#616161</color>
+    <color name="gray_text_dark">#222222</color>
+    <color name="gray_pressed">#9ccc</color>
+    <color name="transparent">#00000000</color>
+    <color name="gray_text_s">#777777</color>
+
+    <color name="blue_alipay">#1b82d2</color>
+    <color name="blue_alipay_dark">#14619d</color>
+    <color name="blue_alipay_icon">#009fe8</color>
+    <color name="blue_dark">#0277BD</color>
+    <color name="blue">#039BE5</color>
+    <color name="blue_light">#33b5e5</color>
+
+    <color name="green_pressed">#118d58</color>
+    <color name="green_search_bg">#3fb179</color>
+    <color name="green_light">#263fb179</color>
+
+    <color name="purple">#ad77e6</color>
+</resources>

+ 13 - 0
app/src/main/res/values/dimen.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <dimen name="margin_default">16dp</dimen>
+    <dimen name="margin_s">8dp</dimen>
+    <dimen name="margin_ss">4dp</dimen>
+    <dimen name="height_split">0.8dp</dimen>
+    <dimen name="height_location">28dp</dimen>
+    <dimen name="width_location">20dp</dimen>
+    <dimen name="height_search">48dp</dimen>
+
+    <dimen name="text_size_p">15sp</dimen>
+    <dimen name="text_size_sub_title">16sp</dimen>
+</resources>

+ 3 - 0
app/src/main/res/values/strings.xml

@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">三个位置</string>
+</resources>

+ 10 - 0
app/src/main/res/values/styles.xml

@@ -0,0 +1,10 @@
+<resources>
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/black</item>
+        <item name="colorPrimaryDark">@color/black</item>
+        <item name="colorAccent">@color/colorAccent</item>
+    </style>
+
+</resources>

+ 17 - 0
app/src/test/java/com/itant/dotonmap/ExampleUnitTest.java

@@ -0,0 +1,17 @@
+package com.itant.dotonmap;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest {
+    @Test
+    public void addition_isCorrect() throws Exception {
+        assertEquals(4, 2 + 2);
+    }
+}

+ 27 - 0
build.gradle

@@ -0,0 +1,27 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+    
+    repositories {
+        google()
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:3.5.2'
+        
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        google()
+        jcenter()
+    }
+}
+
+task clean(type: Delete) {
+    delete rootProject.buildDir
+}

+ 18 - 0
gradle.properties

@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+Android.useDeprecatedNdk=true

TEMPAT SAMPAH
gradle/wrapper/gradle-wrapper.jar


+ 6 - 0
gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,6 @@
+#Thu Sep 03 04:19:07 CST 2020
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip

+ 160 - 0
gradlew

@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

+ 90 - 0
gradlew.bat

@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 32 - 0
library/build.gradle

@@ -0,0 +1,32 @@
+apply plugin: 'com.android.library'
+
+android {
+    compileSdkVersion 27
+
+    defaultConfig {
+        minSdkVersion 14
+        targetSdkVersion 27
+        versionCode 1
+        versionName "1.0"
+
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+dependencies {
+    compile fileTree(dir: 'libs', include: ['*.jar'])
+    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+        exclude group: 'com.android.support', module: 'support-annotations'
+    })
+    testCompile 'junit:junit:4.12'
+
+    compile 'com.android.support:design:27.1.1'
+    compile 'com.android.support:appcompat-v7:27.1.1'
+}

+ 17 - 0
library/proguard-rules.pro

@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in D:\software\work\assdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class title to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}

+ 26 - 0
library/src/androidTest/java/com/itant/library/ExampleInstrumentedTest.java

@@ -0,0 +1,26 @@
+package com.itant.library;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumentation test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() throws Exception {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getTargetContext();
+
+        assertEquals("com.itant.library.test", appContext.getPackageName());
+    }
+}

+ 8 - 0
library/src/main/AndroidManifest.xml

@@ -0,0 +1,8 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itant.library">
+
+    <application android:allowBackup="true" android:label="@string/app_name"
+        android:supportsRtl="true">
+
+    </application>
+
+</manifest>

+ 8 - 0
library/src/main/java/com/itant/library/Placeholder.java

@@ -0,0 +1,8 @@
+package com.itant.library;
+
+/**
+ * Created by iTant on 2017/3/27.
+ */
+
+public class Placeholder {
+}

+ 41 - 0
library/src/main/java/com/itant/library/abslistview/CommonAdapter.java

@@ -0,0 +1,41 @@
+package com.itant.library.abslistview;
+
+import android.content.Context;
+
+
+import com.itant.library.abslistview.base.ItemViewDelegate;
+
+import java.util.List;
+
+public abstract class CommonAdapter<T> extends MultiItemTypeAdapter<T>
+{
+
+    public CommonAdapter(Context context, final int layoutId, List<T> datas)
+    {
+        super(context, datas);
+
+        addItemViewDelegate(new ItemViewDelegate<T>()
+        {
+            @Override
+            public int getItemViewLayoutId()
+            {
+                return layoutId;
+            }
+
+            @Override
+            public boolean isForViewType(T item, int position)
+            {
+                return true;
+            }
+
+            @Override
+            public void convert(ViewHolder holder, T t, int position)
+            {
+                CommonAdapter.this.convert(holder, t, position);
+            }
+        });
+    }
+
+    protected abstract void convert(ViewHolder viewHolder, T item, int position);
+
+}

+ 98 - 0
library/src/main/java/com/itant/library/abslistview/MultiItemTypeAdapter.java

@@ -0,0 +1,98 @@
+package com.itant.library.abslistview;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+
+import com.itant.library.abslistview.base.ItemViewDelegate;
+import com.itant.library.abslistview.base.ItemViewDelegateManager;
+
+import java.util.List;
+
+public class MultiItemTypeAdapter<T> extends BaseAdapter {
+    protected Context mContext;
+    protected List<T> mDatas;
+
+    private ItemViewDelegateManager mItemViewDelegateManager;
+
+
+    public MultiItemTypeAdapter(Context context, List<T> datas) {
+        this.mContext = context;
+        this.mDatas = datas;
+        mItemViewDelegateManager = new ItemViewDelegateManager();
+    }
+
+    public MultiItemTypeAdapter addItemViewDelegate(ItemViewDelegate<T> itemViewDelegate) {
+        mItemViewDelegateManager.addDelegate(itemViewDelegate);
+        return this;
+    }
+
+    private boolean useItemViewDelegateManager() {
+        return mItemViewDelegateManager.getItemViewDelegateCount() > 0;
+    }
+
+    @Override
+    public int getViewTypeCount() {
+        if (useItemViewDelegateManager())
+            return mItemViewDelegateManager.getItemViewDelegateCount();
+        return super.getViewTypeCount();
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        if (useItemViewDelegateManager()) {
+            int viewType = mItemViewDelegateManager.getItemViewType(mDatas.get(position), position);
+            return viewType;
+        }
+        return super.getItemViewType(position);
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        ItemViewDelegate itemViewDelegate = mItemViewDelegateManager.getItemViewDelegate(mDatas.get(position), position);
+        int layoutId = itemViewDelegate.getItemViewLayoutId();
+        ViewHolder viewHolder = null ;
+        if (convertView == null)
+        {
+            View itemView = LayoutInflater.from(mContext).inflate(layoutId, parent,
+                    false);
+            viewHolder = new ViewHolder(mContext, itemView, parent, position);
+            viewHolder.mLayoutId = layoutId;
+            onViewHolderCreated(viewHolder,viewHolder.getConvertView());
+        } else
+        {
+            viewHolder = (ViewHolder) convertView.getTag();
+            viewHolder.mPosition = position;
+        }
+
+
+        convert(viewHolder, getItem(position), position);
+        return viewHolder.getConvertView();
+    }
+
+    protected void convert(ViewHolder viewHolder, T item, int position) {
+        mItemViewDelegateManager.convert(viewHolder, item, position);
+    }
+
+    public void onViewHolderCreated(ViewHolder holder , View itemView )
+    {}
+
+    @Override
+    public int getCount() {
+        return mDatas.size();
+    }
+
+    @Override
+    public T getItem(int position) {
+        return mDatas.get(position);
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return position;
+    }
+
+
+}

+ 290 - 0
library/src/main/java/com/itant/library/abslistview/ViewHolder.java

@@ -0,0 +1,290 @@
+package com.itant.library.abslistview;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Paint;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.text.util.Linkify;
+import android.util.SparseArray;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AlphaAnimation;
+import android.widget.Checkable;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.RatingBar;
+import android.widget.TextView;
+
+public class ViewHolder
+{
+    private SparseArray<View> mViews;
+    protected int mPosition;
+    private View mConvertView;
+    private Context mContext;
+    protected int mLayoutId;
+
+    public ViewHolder(Context context, View itemView, ViewGroup parent, int position)
+    {
+        mContext = context;
+        mConvertView = itemView;
+        mPosition = position;
+        mViews = new SparseArray<View>();
+        mConvertView.setTag(this);
+    }
+
+
+    public static ViewHolder get(Context context, View convertView,
+                                 ViewGroup parent, int layoutId, int position)
+    {
+        if (convertView == null)
+        {
+            View itemView = LayoutInflater.from(context).inflate(layoutId, parent,
+                    false);
+            ViewHolder holder = new ViewHolder(context, itemView, parent, position);
+            holder.mLayoutId = layoutId;
+            return holder;
+        } else
+        {
+            ViewHolder holder = (ViewHolder) convertView.getTag();
+            holder.mPosition = position;
+            return holder;
+        }
+    }
+
+
+    /**
+     * 通过viewId获取控件
+     *
+     * @param viewId
+     * @return
+     */
+    public <T extends View> T getView(int viewId)
+    {
+        View view = mViews.get(viewId);
+        if (view == null)
+        {
+            view = mConvertView.findViewById(viewId);
+            mViews.put(viewId, view);
+        }
+        return (T) view;
+    }
+
+    public View getConvertView()
+    {
+        return mConvertView;
+    }
+
+    public int getLayoutId()
+    {
+        return mLayoutId;
+    }
+
+    public void updatePosition(int position)
+    {
+        mPosition = position;
+    }
+
+    public int getItemPosition()
+    {
+        return mPosition;
+    }
+
+
+    /****以下为辅助方法*****/
+
+    /**
+     * 设置TextView的值
+     *
+     * @param viewId
+     * @param text
+     * @return
+     */
+    public ViewHolder setText(int viewId, String text)
+    {
+        TextView tv = getView(viewId);
+        tv.setText(text);
+        return this;
+    }
+
+    public ViewHolder setImageResource(int viewId, int resId)
+    {
+        ImageView view = getView(viewId);
+        view.setImageResource(resId);
+        return this;
+    }
+
+    public ViewHolder setImageBitmap(int viewId, Bitmap bitmap)
+    {
+        ImageView view = getView(viewId);
+        view.setImageBitmap(bitmap);
+        return this;
+    }
+
+    public ViewHolder setImageDrawable(int viewId, Drawable drawable)
+    {
+        ImageView view = getView(viewId);
+        view.setImageDrawable(drawable);
+        return this;
+    }
+
+    public ViewHolder setBackgroundColor(int viewId, int color)
+    {
+        View view = getView(viewId);
+        view.setBackgroundColor(color);
+        return this;
+    }
+
+    public ViewHolder setBackgroundRes(int viewId, int backgroundRes)
+    {
+        View view = getView(viewId);
+        view.setBackgroundResource(backgroundRes);
+        return this;
+    }
+
+    public ViewHolder setTextColor(int viewId, int textColor)
+    {
+        TextView view = getView(viewId);
+        view.setTextColor(textColor);
+        return this;
+    }
+
+    public ViewHolder setTextColorRes(int viewId, int textColorRes)
+    {
+        TextView view = getView(viewId);
+        view.setTextColor(mContext.getResources().getColor(textColorRes));
+        return this;
+    }
+
+    @SuppressLint("NewApi")
+    public ViewHolder setAlpha(int viewId, float value)
+    {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
+        {
+            getView(viewId).setAlpha(value);
+        } else
+        {
+            // Pre-honeycomb hack to set Alpha value
+            AlphaAnimation alpha = new AlphaAnimation(value, value);
+            alpha.setDuration(0);
+            alpha.setFillAfter(true);
+            getView(viewId).startAnimation(alpha);
+        }
+        return this;
+    }
+
+    public ViewHolder setVisible(int viewId, boolean visible)
+    {
+        View view = getView(viewId);
+        view.setVisibility(visible ? View.VISIBLE : View.GONE);
+        return this;
+    }
+
+    public ViewHolder linkify(int viewId)
+    {
+        TextView view = getView(viewId);
+        Linkify.addLinks(view, Linkify.ALL);
+        return this;
+    }
+
+    public ViewHolder setTypeface(Typeface typeface, int... viewIds)
+    {
+        for (int viewId : viewIds)
+        {
+            TextView view = getView(viewId);
+            view.setTypeface(typeface);
+            view.setPaintFlags(view.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
+        }
+        return this;
+    }
+
+    public ViewHolder setProgress(int viewId, int progress)
+    {
+        ProgressBar view = getView(viewId);
+        view.setProgress(progress);
+        return this;
+    }
+
+    public ViewHolder setProgress(int viewId, int progress, int max)
+    {
+        ProgressBar view = getView(viewId);
+        view.setMax(max);
+        view.setProgress(progress);
+        return this;
+    }
+
+    public ViewHolder setMax(int viewId, int max)
+    {
+        ProgressBar view = getView(viewId);
+        view.setMax(max);
+        return this;
+    }
+
+    public ViewHolder setRating(int viewId, float rating)
+    {
+        RatingBar view = getView(viewId);
+        view.setRating(rating);
+        return this;
+    }
+
+    public ViewHolder setRating(int viewId, float rating, int max)
+    {
+        RatingBar view = getView(viewId);
+        view.setMax(max);
+        view.setRating(rating);
+        return this;
+    }
+
+    public ViewHolder setTag(int viewId, Object tag)
+    {
+        View view = getView(viewId);
+        view.setTag(tag);
+        return this;
+    }
+
+    public ViewHolder setTag(int viewId, int key, Object tag)
+    {
+        View view = getView(viewId);
+        view.setTag(key, tag);
+        return this;
+    }
+
+    public ViewHolder setChecked(int viewId, boolean checked)
+    {
+        Checkable view = (Checkable) getView(viewId);
+        view.setChecked(checked);
+        return this;
+    }
+
+    /**
+     * 关于事件的
+     */
+    public ViewHolder setOnClickListener(int viewId,
+                                         View.OnClickListener listener)
+    {
+        View view = getView(viewId);
+        view.setOnClickListener(listener);
+        return this;
+    }
+
+    public ViewHolder setOnTouchListener(int viewId,
+                                         View.OnTouchListener listener)
+    {
+        View view = getView(viewId);
+        view.setOnTouchListener(listener);
+        return this;
+    }
+
+    public ViewHolder setOnLongClickListener(int viewId,
+                                             View.OnLongClickListener listener)
+    {
+        View view = getView(viewId);
+        view.setOnLongClickListener(listener);
+        return this;
+    }
+
+
+}

+ 20 - 0
library/src/main/java/com/itant/library/abslistview/base/ItemViewDelegate.java

@@ -0,0 +1,20 @@
+package com.itant.library.abslistview.base;
+
+
+import com.itant.library.abslistview.ViewHolder;
+
+/**
+ * Created by iTant on 2017/1/15.
+ */
+public interface ItemViewDelegate<T>
+{
+
+    public abstract int getItemViewLayoutId();
+
+    public abstract boolean isForViewType(T item, int position);
+
+    public abstract void convert(ViewHolder holder, T t, int position);
+
+
+
+}

+ 133 - 0
library/src/main/java/com/itant/library/abslistview/base/ItemViewDelegateManager.java

@@ -0,0 +1,133 @@
+package com.itant.library.abslistview.base;
+
+import android.support.v4.util.SparseArrayCompat;
+
+import com.itant.library.abslistview.ViewHolder;
+
+
+/**
+ * Created by iTant on 2017/1/15.
+ */
+public class ItemViewDelegateManager<T>
+{
+    SparseArrayCompat<ItemViewDelegate<T>> delegates = new SparseArrayCompat();
+
+    public int getItemViewDelegateCount()
+    {
+        return delegates.size();
+    }
+
+    public ItemViewDelegateManager<T> addDelegate(ItemViewDelegate<T> delegate)
+    {
+        int viewType = delegates.size();
+        if (delegate != null)
+        {
+            delegates.put(viewType, delegate);
+            viewType++;
+        }
+        return this;
+    }
+
+    public ItemViewDelegateManager<T> addDelegate(int viewType, ItemViewDelegate<T> delegate)
+    {
+        if (delegates.get(viewType) != null)
+        {
+            throw new IllegalArgumentException(
+                    "An ItemViewDelegate is already registered for the viewType = "
+                            + viewType
+                            + ". Already registered ItemViewDelegate is "
+                            + delegates.get(viewType));
+        }
+        delegates.put(viewType, delegate);
+        return this;
+    }
+
+    public ItemViewDelegateManager<T> removeDelegate(ItemViewDelegate<T> delegate)
+    {
+        if (delegate == null)
+        {
+            throw new NullPointerException("ItemViewDelegate is null");
+        }
+        int indexToRemove = delegates.indexOfValue(delegate);
+
+        if (indexToRemove >= 0)
+        {
+            delegates.removeAt(indexToRemove);
+        }
+        return this;
+    }
+
+    public ItemViewDelegateManager<T> removeDelegate(int itemType)
+    {
+        int indexToRemove = delegates.indexOfKey(itemType);
+
+        if (indexToRemove >= 0)
+        {
+            delegates.removeAt(indexToRemove);
+        }
+        return this;
+    }
+
+    public int getItemViewType(T item, int position)
+    {
+        int delegatesCount = delegates.size();
+        for (int i = delegatesCount - 1; i >= 0; i--)
+        {
+            ItemViewDelegate<T> delegate = delegates.valueAt(i);
+            if (delegate.isForViewType(item, position))
+            {
+                return delegates.keyAt(i);
+            }
+        }
+        throw new IllegalArgumentException(
+                "No ItemViewDelegate added that matches position=" + position + " in data source");
+    }
+
+    public void convert(ViewHolder holder, T item, int position)
+    {
+        int delegatesCount = delegates.size();
+        for (int i = 0; i < delegatesCount; i++)
+        {
+            ItemViewDelegate<T> delegate = delegates.valueAt(i);
+
+            if (delegate.isForViewType(item, position))
+            {
+                delegate.convert(holder, item, position);
+                return;
+            }
+        }
+        throw new IllegalArgumentException(
+                "No ItemViewDelegateManager added that matches position=" + position + " in data source");
+    }
+
+
+    public int getItemViewLayoutId(int viewType)
+    {
+        return delegates.get(viewType).getItemViewLayoutId();
+    }
+
+    public int getItemViewType(ItemViewDelegate itemViewDelegate)
+    {
+        return delegates.indexOfValue(itemViewDelegate);
+    }
+
+    public ItemViewDelegate getItemViewDelegate(T item, int position)
+    {
+        int delegatesCount = delegates.size();
+        for (int i = delegatesCount - 1; i >= 0; i--)
+        {
+            ItemViewDelegate<T> delegate = delegates.valueAt(i);
+            if (delegate.isForViewType(item, position))
+            {
+                return delegate;
+            }
+        }
+        throw new IllegalArgumentException(
+                "No ItemViewDelegate added that matches position=" + position + " in data source");
+    }
+
+    public int getItemViewLayoutId(T item, int position)
+    {
+        return getItemViewDelegate(item,position).getItemViewLayoutId();
+    }
+}

+ 54 - 0
library/src/main/java/com/itant/library/recyclerview/CommonAdapter.java

@@ -0,0 +1,54 @@
+package com.itant.library.recyclerview;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+
+import com.itant.library.recyclerview.base.ItemViewDelegate;
+import com.itant.library.recyclerview.base.ViewHolder;
+
+import java.util.List;
+
+/**
+ * Created by iTant on 2017/1/15.
+ */
+public abstract class CommonAdapter<T> extends MultiItemTypeAdapter<T>
+{
+    protected Context mContext;
+    protected int mLayoutId;
+    protected List<T> mDatas;
+    protected LayoutInflater mInflater;
+
+    public CommonAdapter(final Context context, final int layoutId, List<T> datas)
+    {
+        super(context, datas);
+        mContext = context;
+        mInflater = LayoutInflater.from(context);
+        mLayoutId = layoutId;
+        mDatas = datas;
+
+        addItemViewDelegate(new ItemViewDelegate<T>()
+        {
+            @Override
+            public int getItemViewLayoutId()
+            {
+                return layoutId;
+            }
+
+            @Override
+            public boolean isForViewType( T item, int position)
+            {
+                return true;
+            }
+
+            @Override
+            public void convert(ViewHolder holder, T t, int position)
+            {
+                CommonAdapter.this.convert(holder, t, position);
+            }
+        });
+    }
+
+    protected abstract void convert(ViewHolder holder, T t, int position);
+
+
+}

+ 131 - 0
library/src/main/java/com/itant/library/recyclerview/MultiItemTypeAdapter.java

@@ -0,0 +1,131 @@
+package com.itant.library.recyclerview;
+
+import android.content.Context;
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.itant.library.recyclerview.base.ItemViewDelegate;
+import com.itant.library.recyclerview.base.ItemViewDelegateManager;
+import com.itant.library.recyclerview.base.ViewHolder;
+
+import java.util.List;
+
+/**
+ * Created by iTant on 2017/1/15.
+ */
+public class MultiItemTypeAdapter<T> extends RecyclerView.Adapter<ViewHolder> {
+    protected Context mContext;
+    protected List<T> mDatas;
+
+    protected ItemViewDelegateManager mItemViewDelegateManager;
+    protected OnItemClickListener mOnItemClickListener;
+
+
+    public MultiItemTypeAdapter(Context context, List<T> datas) {
+        mContext = context;
+        mDatas = datas;
+        mItemViewDelegateManager = new ItemViewDelegateManager();
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        if (!useItemViewDelegateManager()) return super.getItemViewType(position);
+        return mItemViewDelegateManager.getItemViewType(mDatas.get(position), position);
+    }
+
+
+    @Override
+    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+        ItemViewDelegate itemViewDelegate = mItemViewDelegateManager.getItemViewDelegate(viewType);
+        int layoutId = itemViewDelegate.getItemViewLayoutId();
+        ViewHolder holder = ViewHolder.createViewHolder(mContext, parent, layoutId);
+        onViewHolderCreated(holder,holder.getConvertView());
+        setListener(parent, holder, viewType);
+        return holder;
+    }
+
+    public void onViewHolderCreated(ViewHolder holder,View itemView){
+
+    }
+
+    public void convert(ViewHolder holder, T t) {
+        mItemViewDelegateManager.convert(holder, t, holder.getAdapterPosition());
+    }
+
+    protected boolean isEnabled(int viewType) {
+        return true;
+    }
+
+
+    protected void setListener(final ViewGroup parent, final ViewHolder viewHolder, int viewType) {
+        if (!isEnabled(viewType)) return;
+        viewHolder.getConvertView().setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (mOnItemClickListener != null) {
+                    int position = viewHolder.getAdapterPosition();
+                    mOnItemClickListener.onItemClick(v, viewHolder , position);
+                }
+            }
+        });
+
+        viewHolder.getConvertView().setOnLongClickListener(new View.OnLongClickListener() {
+            @Override
+            public boolean onLongClick(View v) {
+                if (mOnItemClickListener != null) {
+                    int position = viewHolder.getAdapterPosition();
+                    return mOnItemClickListener.onItemLongClick(v, viewHolder, position);
+                }
+                return false;
+            }
+        });
+    }
+
+    private int mLastPosition=-1;// 设为-1是为了让动画从第0个item出现
+    @Override
+    public void onBindViewHolder(ViewHolder holder, int position) {
+        convert(holder, mDatas.get(position));
+        /*if (position > mLastPosition && !isFooterPosition(position)) {
+            // 一个一个出现的动画
+            Animation animation = AnimationUtils.loadAnimation(holder.itemView.getContext(), R.anim.anim_bottom_in);
+            holder.itemView.startAnimation(animation);
+            mLastPosition = position;
+        }*/
+    }
+
+    @Override
+    public int getItemCount() {
+        int itemCount = mDatas.size();
+        return itemCount;
+    }
+
+
+    public List<T> getDatas() {
+        return mDatas;
+    }
+
+    public MultiItemTypeAdapter addItemViewDelegate(ItemViewDelegate<T> itemViewDelegate) {
+        mItemViewDelegateManager.addDelegate(itemViewDelegate);
+        return this;
+    }
+
+    public MultiItemTypeAdapter addItemViewDelegate(int viewType, ItemViewDelegate<T> itemViewDelegate) {
+        mItemViewDelegateManager.addDelegate(viewType, itemViewDelegate);
+        return this;
+    }
+
+    protected boolean useItemViewDelegateManager() {
+        return mItemViewDelegateManager.getItemViewDelegateCount() > 0;
+    }
+
+    public interface OnItemClickListener {
+        void onItemClick(View view, RecyclerView.ViewHolder holder, int position);
+
+        boolean onItemLongClick(View view, RecyclerView.ViewHolder holder, int position);
+    }
+
+    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
+        this.mOnItemClickListener = onItemClickListener;
+    }
+}

+ 16 - 0
library/src/main/java/com/itant/library/recyclerview/base/ItemViewDelegate.java

@@ -0,0 +1,16 @@
+package com.itant.library.recyclerview.base;
+
+
+/**
+ * Created by iTant on 2017/1/15.
+ */
+public interface ItemViewDelegate<T>
+{
+
+    int getItemViewLayoutId();
+
+    boolean isForViewType(T item, int position);
+
+    void convert(ViewHolder holder, T t, int position);
+
+}

+ 116 - 0
library/src/main/java/com/itant/library/recyclerview/base/ItemViewDelegateManager.java

@@ -0,0 +1,116 @@
+package com.itant.library.recyclerview.base;
+
+import android.support.v4.util.SparseArrayCompat;
+
+
+/**
+ * Created by iTant on 2017/1/15.
+ */
+public class ItemViewDelegateManager<T>
+{
+    SparseArrayCompat<ItemViewDelegate<T>> delegates = new SparseArrayCompat();
+
+    public int getItemViewDelegateCount()
+    {
+        return delegates.size();
+    }
+
+    public ItemViewDelegateManager<T> addDelegate(ItemViewDelegate<T> delegate)
+    {
+        int viewType = delegates.size();
+        if (delegate != null)
+        {
+            delegates.put(viewType, delegate);
+            viewType++;
+        }
+        return this;
+    }
+
+    public ItemViewDelegateManager<T> addDelegate(int viewType, ItemViewDelegate<T> delegate)
+    {
+        if (delegates.get(viewType) != null)
+        {
+            throw new IllegalArgumentException(
+                    "An ItemViewDelegate is already registered for the viewType = "
+                            + viewType
+                            + ". Already registered ItemViewDelegate is "
+                            + delegates.get(viewType));
+        }
+        delegates.put(viewType, delegate);
+        return this;
+    }
+
+    public ItemViewDelegateManager<T> removeDelegate(ItemViewDelegate<T> delegate)
+    {
+        if (delegate == null)
+        {
+            throw new NullPointerException("ItemViewDelegate is null");
+        }
+        int indexToRemove = delegates.indexOfValue(delegate);
+
+        if (indexToRemove >= 0)
+        {
+            delegates.removeAt(indexToRemove);
+        }
+        return this;
+    }
+
+    public ItemViewDelegateManager<T> removeDelegate(int itemType)
+    {
+        int indexToRemove = delegates.indexOfKey(itemType);
+
+        if (indexToRemove >= 0)
+        {
+            delegates.removeAt(indexToRemove);
+        }
+        return this;
+    }
+
+    public int getItemViewType(T item, int position)
+    {
+        int delegatesCount = delegates.size();
+        for (int i = delegatesCount - 1; i >= 0; i--)
+        {
+            ItemViewDelegate<T> delegate = delegates.valueAt(i);
+            if (delegate.isForViewType( item, position))
+            {
+                return delegates.keyAt(i);
+            }
+        }
+        throw new IllegalArgumentException(
+                "No ItemViewDelegate added that matches position=" + position + " in data source");
+    }
+
+    public void convert(ViewHolder holder, T item, int position)
+    {
+        int delegatesCount = delegates.size();
+        for (int i = 0; i < delegatesCount; i++)
+        {
+            ItemViewDelegate<T> delegate = delegates.valueAt(i);
+
+            if (delegate.isForViewType( item, position))
+            {
+                delegate.convert(holder, item, position);
+                return;
+            }
+        }
+        throw new IllegalArgumentException(
+                "No ItemViewDelegateManager added that matches position=" + position + " in data source");
+    }
+
+
+    public ItemViewDelegate getItemViewDelegate(int viewType)
+    {
+        return delegates.get(viewType);
+    }
+
+    public int getItemViewLayoutId(int viewType)
+    {
+        return getItemViewDelegate(viewType).getItemViewLayoutId();
+    }
+
+    public int getItemViewType(ItemViewDelegate itemViewDelegate)
+    {
+        return delegates.indexOfValue(itemViewDelegate);
+    }
+}

+ 310 - 0
library/src/main/java/com/itant/library/recyclerview/base/ViewHolder.java

@@ -0,0 +1,310 @@
+package com.itant.library.recyclerview.base;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+import android.os.Build;
+import android.support.v7.widget.RecyclerView;
+import android.text.util.Linkify;
+import android.util.SparseArray;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AlphaAnimation;
+import android.widget.Checkable;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.RatingBar;
+import android.widget.TextView;
+
+public class ViewHolder extends RecyclerView.ViewHolder/* implements AnimateViewHolder*/
+{
+    private SparseArray<View> mViews;
+    private View mConvertView;
+    private Context mContext;
+
+    public ViewHolder(Context context, View itemView)
+    {
+        super(itemView);
+        mContext = context;
+        mConvertView = itemView;
+        mViews = new SparseArray<View>();
+    }
+
+
+    public static ViewHolder createViewHolder(Context context, View itemView)
+    {
+        ViewHolder holder = new ViewHolder(context, itemView);
+        return holder;
+    }
+
+    public static ViewHolder createViewHolder(Context context,
+                                              ViewGroup parent, int layoutId)
+    {
+        View itemView = LayoutInflater.from(context).inflate(layoutId, parent,
+                false);
+        ViewHolder holder = new ViewHolder(context, itemView);
+        return holder;
+    }
+
+    /**
+     * 通过viewId获取控件
+     *
+     * @param viewId
+     * @return
+     */
+    public <T extends View> T getView(int viewId)
+    {
+        View view = mViews.get(viewId);
+        if (view == null)
+        {
+            view = mConvertView.findViewById(viewId);
+            mViews.put(viewId, view);
+        }
+        return (T) view;
+    }
+
+    public View getConvertView()
+    {
+        return mConvertView;
+    }
+
+
+
+
+    /****以下为辅助方法*****/
+
+    /**
+     * 设置TextView的值
+     *
+     * @param viewId
+     * @param text
+     * @return
+     */
+    public ViewHolder setText(int viewId, String text)
+    {
+        TextView tv = getView(viewId);
+        tv.setText(text);
+        return this;
+    }
+
+    public ViewHolder setImageResource(int viewId, int resId)
+    {
+        ImageView view = getView(viewId);
+        view.setImageResource(resId);
+        return this;
+    }
+
+    public ViewHolder setImageBitmap(int viewId, Bitmap bitmap)
+    {
+        ImageView view = getView(viewId);
+        view.setImageBitmap(bitmap);
+        return this;
+    }
+
+    public ViewHolder setImageDrawable(int viewId, Drawable drawable)
+    {
+        ImageView view = getView(viewId);
+        view.setImageDrawable(drawable);
+        return this;
+    }
+
+    public ViewHolder setBackgroundColor(int viewId, int color)
+    {
+        View view = getView(viewId);
+        view.setBackgroundColor(color);
+        return this;
+    }
+
+    public ViewHolder setBackgroundRes(int viewId, int backgroundRes)
+    {
+        View view = getView(viewId);
+        view.setBackgroundResource(backgroundRes);
+        return this;
+    }
+
+    public ViewHolder setTextColor(int viewId, int textColor)
+    {
+        TextView view = getView(viewId);
+        view.setTextColor(textColor);
+        return this;
+    }
+
+    public ViewHolder setTextColorRes(int viewId, int textColorRes)
+    {
+        TextView view = getView(viewId);
+        view.setTextColor(mContext.getResources().getColor(textColorRes));
+        return this;
+    }
+
+    @SuppressLint("NewApi")
+    public ViewHolder setAlpha(int viewId, float value)
+    {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
+        {
+            getView(viewId).setAlpha(value);
+        } else
+        {
+            // Pre-honeycomb hack to set Alpha value
+            AlphaAnimation alpha = new AlphaAnimation(value, value);
+            alpha.setDuration(0);
+            alpha.setFillAfter(true);
+            getView(viewId).startAnimation(alpha);
+        }
+        return this;
+    }
+
+    public ViewHolder setVisible(int viewId, boolean visible)
+    {
+        View view = getView(viewId);
+        view.setVisibility(visible ? View.VISIBLE : View.GONE);
+        return this;
+    }
+
+    public ViewHolder linkify(int viewId)
+    {
+        TextView view = getView(viewId);
+        Linkify.addLinks(view, Linkify.ALL);
+        return this;
+    }
+
+    public ViewHolder setTypeface(Typeface typeface, int... viewIds)
+    {
+        for (int viewId : viewIds)
+        {
+            TextView view = getView(viewId);
+            view.setTypeface(typeface);
+            view.setPaintFlags(view.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
+        }
+        return this;
+    }
+
+    public ViewHolder setProgress(int viewId, int progress)
+    {
+        ProgressBar view = getView(viewId);
+        view.setProgress(progress);
+        return this;
+    }
+
+    public ViewHolder setProgress(int viewId, int progress, int max)
+    {
+        ProgressBar view = getView(viewId);
+        view.setMax(max);
+        view.setProgress(progress);
+        return this;
+    }
+
+    public ViewHolder setMax(int viewId, int max)
+    {
+        ProgressBar view = getView(viewId);
+        view.setMax(max);
+        return this;
+    }
+
+    public ViewHolder setRating(int viewId, float rating)
+    {
+        RatingBar view = getView(viewId);
+        LayerDrawable stars = (LayerDrawable) view.getProgressDrawable();
+        stars.getDrawable(2).setColorFilter(Color.parseColor("#eb002f"), PorterDuff.Mode.SRC_ATOP);
+        view.setRating(rating);
+        return this;
+    }
+
+    public ViewHolder setRating(int viewId, float rating, int max)
+    {
+        RatingBar view = getView(viewId);
+        view.setMax(max);
+        view.setRating(rating);
+        return this;
+    }
+
+    public ViewHolder setTag(int viewId, Object tag)
+    {
+        View view = getView(viewId);
+        view.setTag(tag);
+        return this;
+    }
+
+    public ViewHolder setTag(int viewId, int key, Object tag)
+    {
+        View view = getView(viewId);
+        view.setTag(key, tag);
+        return this;
+    }
+
+    public ViewHolder setChecked(int viewId, boolean checked)
+    {
+        Checkable view = (Checkable) getView(viewId);
+        view.setChecked(checked);
+        return this;
+    }
+
+    /**
+     * 关于事件的
+     */
+    public ViewHolder setOnClickListener(int viewId,
+                                         View.OnClickListener listener)
+    {
+        View view = getView(viewId);
+        view.setOnClickListener(listener);
+        return this;
+    }
+
+    public ViewHolder setOnTouchListener(int viewId,
+                                         View.OnTouchListener listener)
+    {
+        View view = getView(viewId);
+        view.setOnTouchListener(listener);
+        return this;
+    }
+
+    public ViewHolder setOnLongClickListener(int viewId,
+                                             View.OnLongClickListener listener)
+    {
+        View view = getView(viewId);
+        view.setOnLongClickListener(listener);
+        return this;
+    }
+
+
+    /*----------------------------------动画----------------------------------*/
+    /*@Override
+    public void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
+        ViewCompat.setTranslationY(itemView, -itemView.getHeight() * 0.3f);
+        ViewCompat.setAlpha(itemView, 0);
+    }
+
+    @Override
+    public void preAnimateRemoveImpl(RecyclerView.ViewHolder holder) {
+
+    }
+
+    @Override
+    public void animateAddImpl(RecyclerView.ViewHolder holder, ViewPropertyAnimatorListener listener) {
+        // 添加的动画
+        ViewCompat.animate(itemView)
+                .translationY(0)
+                .alpha(1)
+                .setDuration(300)
+                .setListener(listener)
+                .start();
+    }
+
+    @Override
+    public void animateRemoveImpl(RecyclerView.ViewHolder holder, ViewPropertyAnimatorListener listener) {
+        // 移除的动画
+        ViewCompat.animate(itemView)
+                .translationY(-itemView.getHeight() * 0.3f)
+                .alpha(0)
+                .setDuration(300)
+                .setListener(listener)
+                .start();
+    }*/
+    /*----------------------------------动画----------------------------------*/
+}

+ 53 - 0
library/src/main/java/com/itant/library/recyclerview/utils/WrapperUtils.java

@@ -0,0 +1,53 @@
+package com.itant.library.recyclerview.utils;
+
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.StaggeredGridLayoutManager;
+import android.view.ViewGroup;
+
+/**
+ * Created by iTant on 2017/1/15.
+ */
+public class WrapperUtils
+{
+    public interface SpanSizeCallback
+    {
+        int getSpanSize(GridLayoutManager layoutManager, GridLayoutManager.SpanSizeLookup oldLookup, int position);
+    }
+
+    public static void onAttachedToRecyclerView(RecyclerView.Adapter innerAdapter, RecyclerView recyclerView, final SpanSizeCallback callback)
+    {
+        innerAdapter.onAttachedToRecyclerView(recyclerView);
+
+        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
+        if (layoutManager instanceof GridLayoutManager)
+        {
+            final GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
+            final GridLayoutManager.SpanSizeLookup spanSizeLookup = gridLayoutManager.getSpanSizeLookup();
+
+            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup()
+            {
+                @Override
+                public int getSpanSize(int position)
+                {
+                    return callback.getSpanSize(gridLayoutManager, spanSizeLookup, position);
+                }
+            });
+            gridLayoutManager.setSpanCount(gridLayoutManager.getSpanCount());
+        }
+    }
+
+    public static void setFullSpan(RecyclerView.ViewHolder holder)
+    {
+        ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
+
+        if (lp != null
+                && lp instanceof StaggeredGridLayoutManager.LayoutParams)
+        {
+
+            StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
+
+            p.setFullSpan(true);
+        }
+    }
+}

+ 124 - 0
library/src/main/java/com/itant/library/recyclerview/wrapper/EmptyWrapper.java

@@ -0,0 +1,124 @@
+package com.itant.library.recyclerview.wrapper;
+
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.itant.library.recyclerview.base.ViewHolder;
+import com.itant.library.recyclerview.utils.WrapperUtils;
+
+/**
+ * Created by iTant on 2017/1/15.
+ */
+public class EmptyWrapper<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder>
+{
+    public static final int ITEM_TYPE_EMPTY = Integer.MAX_VALUE - 1;
+
+    private RecyclerView.Adapter mInnerAdapter;
+    private View mEmptyView;
+    private int mEmptyLayoutId;
+
+
+    public EmptyWrapper(RecyclerView.Adapter adapter)
+    {
+        mInnerAdapter = adapter;
+    }
+
+    private boolean isEmpty()
+    {
+        return (mEmptyView != null || mEmptyLayoutId != 0) && mInnerAdapter.getItemCount() == 0;
+    }
+
+    @Override
+    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
+    {
+        if (isEmpty())
+        {
+            ViewHolder holder;
+            if (mEmptyView != null)
+            {
+                holder = ViewHolder.createViewHolder(parent.getContext(), mEmptyView);
+            } else
+            {
+                holder = ViewHolder.createViewHolder(parent.getContext(), parent, mEmptyLayoutId);
+            }
+            return holder;
+        }
+        return mInnerAdapter.onCreateViewHolder(parent, viewType);
+    }
+
+    @Override
+    public void onAttachedToRecyclerView(RecyclerView recyclerView)
+    {
+        WrapperUtils.onAttachedToRecyclerView(mInnerAdapter, recyclerView, new WrapperUtils.SpanSizeCallback()
+        {
+            @Override
+            public int getSpanSize(GridLayoutManager gridLayoutManager, GridLayoutManager.SpanSizeLookup oldLookup, int position)
+            {
+                if (isEmpty())
+                {
+                    return gridLayoutManager.getSpanCount();
+                }
+                if (oldLookup != null)
+                {
+                    return oldLookup.getSpanSize(position);
+                }
+                return 1;
+            }
+        });
+
+
+    }
+
+    @Override
+    public void onViewAttachedToWindow(RecyclerView.ViewHolder holder)
+    {
+        mInnerAdapter.onViewAttachedToWindow(holder);
+        if (isEmpty())
+        {
+            WrapperUtils.setFullSpan(holder);
+        }
+    }
+
+
+    @Override
+    public int getItemViewType(int position)
+    {
+        if (isEmpty())
+        {
+            return ITEM_TYPE_EMPTY;
+        }
+        return mInnerAdapter.getItemViewType(position);
+    }
+
+    @Override
+    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
+    {
+        if (isEmpty())
+        {
+            return;
+        }
+        mInnerAdapter.onBindViewHolder(holder, position);
+    }
+
+    @Override
+    public int getItemCount()
+    {
+        if (isEmpty()) return 1;
+        return mInnerAdapter.getItemCount();
+    }
+
+
+
+    public void setEmptyView(View emptyView)
+    {
+        mEmptyView = emptyView;
+    }
+
+    public void setEmptyView(int layoutId)
+    {
+        mEmptyLayoutId = layoutId;
+    }
+
+}

+ 149 - 0
library/src/main/java/com/itant/library/recyclerview/wrapper/HeaderAndFooterWrapper.java

@@ -0,0 +1,149 @@
+package com.itant.library.recyclerview.wrapper;
+
+import android.support.v4.util.SparseArrayCompat;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.itant.library.recyclerview.base.ViewHolder;
+import com.itant.library.recyclerview.utils.WrapperUtils;
+
+
+public class HeaderAndFooterWrapper<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder>
+{
+    private static final int BASE_ITEM_TYPE_HEADER = 100000;
+    private static final int BASE_ITEM_TYPE_FOOTER = 200000;
+
+    private SparseArrayCompat<View> mHeaderViews = new SparseArrayCompat<>();
+    private SparseArrayCompat<View> mFootViews = new SparseArrayCompat<>();
+
+    private RecyclerView.Adapter mInnerAdapter;
+
+    public HeaderAndFooterWrapper(RecyclerView.Adapter adapter)
+    {
+        mInnerAdapter = adapter;
+    }
+
+    @Override
+    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
+    {
+        if (mHeaderViews.get(viewType) != null)
+        {
+            ViewHolder holder = ViewHolder.createViewHolder(parent.getContext(), mHeaderViews.get(viewType));
+            return holder;
+
+        } else if (mFootViews.get(viewType) != null)
+        {
+            ViewHolder holder = ViewHolder.createViewHolder(parent.getContext(), mFootViews.get(viewType));
+            return holder;
+        }
+        return mInnerAdapter.onCreateViewHolder(parent, viewType);
+    }
+
+    @Override
+    public int getItemViewType(int position)
+    {
+        if (isHeaderViewPos(position))
+        {
+            return mHeaderViews.keyAt(position);
+        } else if (isFooterViewPos(position))
+        {
+            return mFootViews.keyAt(position - getHeadersCount() - getRealItemCount());
+        }
+        return mInnerAdapter.getItemViewType(position - getHeadersCount());
+    }
+
+    private int getRealItemCount()
+    {
+        return mInnerAdapter.getItemCount();
+    }
+
+
+    @Override
+    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
+    {
+        if (isHeaderViewPos(position))
+        {
+            return;
+        }
+        if (isFooterViewPos(position))
+        {
+            return;
+        }
+        mInnerAdapter.onBindViewHolder(holder, position - getHeadersCount());
+    }
+
+    @Override
+    public int getItemCount()
+    {
+        return getHeadersCount() + getFootersCount() + getRealItemCount();
+    }
+
+    @Override
+    public void onAttachedToRecyclerView(RecyclerView recyclerView)
+    {
+        WrapperUtils.onAttachedToRecyclerView(mInnerAdapter, recyclerView, new WrapperUtils.SpanSizeCallback()
+        {
+            @Override
+            public int getSpanSize(GridLayoutManager layoutManager, GridLayoutManager.SpanSizeLookup oldLookup, int position)
+            {
+                int viewType = getItemViewType(position);
+                if (mHeaderViews.get(viewType) != null)
+                {
+                    return layoutManager.getSpanCount();
+                } else if (mFootViews.get(viewType) != null)
+                {
+                    return layoutManager.getSpanCount();
+                }
+                if (oldLookup != null)
+                    return oldLookup.getSpanSize(position);
+                return 1;
+            }
+        });
+    }
+
+    @Override
+    public void onViewAttachedToWindow(RecyclerView.ViewHolder holder)
+    {
+        mInnerAdapter.onViewAttachedToWindow(holder);
+        int position = holder.getLayoutPosition();
+        if (isHeaderViewPos(position) || isFooterViewPos(position))
+        {
+            WrapperUtils.setFullSpan(holder);
+        }
+    }
+
+    private boolean isHeaderViewPos(int position)
+    {
+        return position < getHeadersCount();
+    }
+
+    private boolean isFooterViewPos(int position)
+    {
+        return position >= getHeadersCount() + getRealItemCount();
+    }
+
+
+    public void addHeaderView(View view)
+    {
+        mHeaderViews.put(mHeaderViews.size() + BASE_ITEM_TYPE_HEADER, view);
+    }
+
+    public void addFootView(View view)
+    {
+        mFootViews.put(mFootViews.size() + BASE_ITEM_TYPE_FOOTER, view);
+    }
+
+    public int getHeadersCount()
+    {
+        return mHeaderViews.size();
+    }
+
+    public int getFootersCount()
+    {
+        return mFootViews.size();
+    }
+
+
+}

+ 159 - 0
library/src/main/java/com/itant/library/recyclerview/wrapper/LoadMoreWrapper.java

@@ -0,0 +1,159 @@
+package com.itant.library.recyclerview.wrapper;
+
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.StaggeredGridLayoutManager;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.itant.library.recyclerview.base.ViewHolder;
+import com.itant.library.recyclerview.utils.WrapperUtils;
+
+
+public class LoadMoreWrapper<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder>
+{
+    public static final int ITEM_TYPE_LOAD_MORE = Integer.MAX_VALUE - 2;
+
+    private RecyclerView.Adapter mInnerAdapter;
+    private View mLoadMoreView;
+    private int mLoadMoreLayoutId;
+
+    public LoadMoreWrapper(RecyclerView.Adapter adapter)
+    {
+        mInnerAdapter = adapter;
+    }
+
+    private boolean hasLoadMore()
+    {
+        return mLoadMoreView != null || mLoadMoreLayoutId != 0;
+    }
+
+
+    private boolean isShowLoadMore(int position)
+    {
+        return hasLoadMore() && (position >= mInnerAdapter.getItemCount());
+    }
+
+    @Override
+    public int getItemViewType(int position)
+    {
+        if (isShowLoadMore(position))
+        {
+            return ITEM_TYPE_LOAD_MORE;
+        }
+        return mInnerAdapter.getItemViewType(position);
+    }
+
+    @Override
+    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
+    {
+        if (viewType == ITEM_TYPE_LOAD_MORE)
+        {
+            ViewHolder holder;
+            if (mLoadMoreView != null)
+            {
+                holder = ViewHolder.createViewHolder(parent.getContext(), mLoadMoreView);
+            } else
+            {
+                holder = ViewHolder.createViewHolder(parent.getContext(), parent, mLoadMoreLayoutId);
+            }
+            return holder;
+        }
+        return mInnerAdapter.onCreateViewHolder(parent, viewType);
+    }
+
+    @Override
+    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
+    {
+        if (isShowLoadMore(position))
+        {
+            if (mOnLoadMoreListener != null)
+            {
+                mOnLoadMoreListener.onLoadMoreRequested();
+            }
+            return;
+        }
+        mInnerAdapter.onBindViewHolder(holder, position);
+    }
+
+    @Override
+    public void onAttachedToRecyclerView(RecyclerView recyclerView)
+    {
+        WrapperUtils.onAttachedToRecyclerView(mInnerAdapter, recyclerView, new WrapperUtils.SpanSizeCallback()
+        {
+            @Override
+            public int getSpanSize(GridLayoutManager layoutManager, GridLayoutManager.SpanSizeLookup oldLookup, int position)
+            {
+                if (isShowLoadMore(position))
+                {
+                    return layoutManager.getSpanCount();
+                }
+                if (oldLookup != null)
+                {
+                    return oldLookup.getSpanSize(position);
+                }
+                return 1;
+            }
+        });
+    }
+
+
+    @Override
+    public void onViewAttachedToWindow(RecyclerView.ViewHolder holder)
+    {
+        mInnerAdapter.onViewAttachedToWindow(holder);
+
+        if (isShowLoadMore(holder.getLayoutPosition()))
+        {
+            setFullSpan(holder);
+        }
+    }
+
+    private void setFullSpan(RecyclerView.ViewHolder holder)
+    {
+        ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
+
+        if (lp != null
+                && lp instanceof StaggeredGridLayoutManager.LayoutParams)
+        {
+            StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
+
+            p.setFullSpan(true);
+        }
+    }
+
+    @Override
+    public int getItemCount()
+    {
+        return mInnerAdapter.getItemCount() + (hasLoadMore() ? 1 : 0);
+    }
+
+
+    public interface OnLoadMoreListener
+    {
+        void onLoadMoreRequested();
+    }
+
+    private OnLoadMoreListener mOnLoadMoreListener;
+
+    public LoadMoreWrapper setOnLoadMoreListener(OnLoadMoreListener loadMoreListener)
+    {
+        if (loadMoreListener != null)
+        {
+            mOnLoadMoreListener = loadMoreListener;
+        }
+        return this;
+    }
+
+    public LoadMoreWrapper setLoadMoreView(View loadMoreView)
+    {
+        mLoadMoreView = loadMoreView;
+        return this;
+    }
+
+    public LoadMoreWrapper setLoadMoreView(int layoutId)
+    {
+        mLoadMoreLayoutId = layoutId;
+        return this;
+    }
+}

+ 13 - 0
library/src/main/res/anim/anim_bottom_in.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:duration="500">
+
+    <translate
+        android:fromYDelta="50%"
+        android:toYDelta="0%"/>
+
+    <alpha
+        android:fromAlpha="0.5"
+        android:toAlpha="1"/>
+
+</set>

+ 4 - 0
library/src/main/res/values-v21/dimen.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <dimen name="fab_margin">16dp</dimen>
+</resources>

+ 11 - 0
library/src/main/res/values/color.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="color_primary_red">#f44336</color>
+    <color name="color_primary_red_dark">#d32f2f</color>
+    <color name="color_primary_green"> #4caf50</color>
+    <color name="color_primary_green_dark">#388e3c</color>
+    <color name="color_primary_blue">#2196f3</color>
+    <color name="color_primary_blue_dark">#1976d2</color>
+    <color name="color_accent_pink">#ff4081</color>
+    <color name="color_shadow">#44000000</color>
+</resources>

+ 5 - 0
library/src/main/res/values/dimen.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <dimen name="tabsHeight">48dp</dimen>
+    <dimen name="fab_margin">0dp</dimen>
+</resources>

+ 3 - 0
library/src/main/res/values/strings.xml

@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">Library</string>
+</resources>

+ 22 - 0
library/src/main/res/values/styles.xml

@@ -0,0 +1,22 @@
+<resources>
+
+    <style name="CustomTheme" parent="Theme.AppCompat.Light.NoActionBar">
+    </style>
+
+    <style name="AppThemeRed" parent="CustomTheme">
+        <item name="colorPrimary">@color/color_primary_red</item>
+        <item name="colorPrimaryDark">@color/color_primary_red_dark</item>
+    </style>
+
+    <style name="AppThemeGreen" parent="CustomTheme">
+        <item name="colorPrimary">@color/color_primary_green</item>
+        <item name="colorPrimaryDark">@color/color_primary_green_dark</item>
+    </style>
+
+    <style name="AppThemeBlue" parent="CustomTheme">
+        <item name="colorPrimary">@color/color_primary_blue</item>
+        <item name="colorPrimaryDark">@color/color_primary_blue_dark</item>
+        <item name="colorAccent">@color/color_accent_pink</item>
+    </style>
+
+</resources>

+ 17 - 0
library/src/test/java/com/itant/library/ExampleUnitTest.java

@@ -0,0 +1,17 @@
+package com.itant.library;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest {
+    @Test
+    public void addition_isCorrect() throws Exception {
+        assertEquals(4, 2 + 2);
+    }
+}

+ 8 - 0
local.properties

@@ -0,0 +1,8 @@
+## This file must *NOT* be checked into Version Control Systems,
+# as it contains information specific to your local configuration.
+#
+# Location of the SDK. This is only used by Gradle.
+# For customization when using a Version Control System, please read the
+# header note.
+#Thu Sep 03 04:07:34 CST 2020
+sdk.dir=E\:\\software\\Android\\newsdk

+ 1 - 0
settings.gradle

@@ -0,0 +1 @@
+include ':app', ':library'