├── settings.gradle
├── art
└── art.gif
├── app
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── fast_empty.png
│ │ │ │ ├── ic_launcher.png
│ │ │ │ ├── fast_item_add.png
│ │ │ │ ├── fast_new_reduce.png
│ │ │ │ ├── fast_panduan_icon.png
│ │ │ │ ├── fast_xuanze_icon.png
│ │ │ │ ├── fast_zhuguan_icon.png
│ │ │ │ ├── ic_launcher_round.png
│ │ │ │ └── fast_new_left_adding.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── img_delete.png
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── drawable
│ │ │ │ ├── number_bg.xml
│ │ │ │ ├── bordors.xml
│ │ │ │ └── ic_launcher_background.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── layout
│ │ │ │ ├── fast_adding.xml
│ │ │ │ ├── fast_item_empty.xml
│ │ │ │ ├── activity_main.xml
│ │ │ │ ├── fast_item_title.xml
│ │ │ │ ├── fast_item_left.xml
│ │ │ │ ├── fast_item_left2.xml
│ │ │ │ ├── fast_item_left3.xml
│ │ │ │ └── fast_tixing_item.xml
│ │ │ └── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── jyuesong
│ │ │ └── dragview2fill
│ │ │ ├── MainActivity.java
│ │ │ ├── FastModel.java
│ │ │ ├── adapter
│ │ │ ├── BaseAdapter.java
│ │ │ └── BaseViewHolder.java
│ │ │ └── dragview
│ │ │ ├── LayoutHelper.java
│ │ │ ├── DragViewGroup.java
│ │ │ └── RecyclerViewHelper.java
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── jyuesong
│ │ │ └── dragview2fill
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── jyuesong
│ │ └── dragview2fill
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
├── .gitignore
└── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── README.md
├── .idea
├── encodings.xml
├── vcs.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── modules.xml
├── runConfigurations.xml
└── misc.xml
├── gradle.properties
├── .gitignore
├── gradlew.bat
└── gradlew
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/art/art.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/art/art.gif
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | DragView2Fill
3 |
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/fast_empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-hdpi/fast_empty.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/img_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-xxhdpi/img_delete.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/fast_item_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-hdpi/fast_item_add.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/fast_new_reduce.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-hdpi/fast_new_reduce.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/fast_panduan_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-hdpi/fast_panduan_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/fast_xuanze_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-hdpi/fast_xuanze_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/fast_zhuguan_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-hdpi/fast_zhuguan_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DragView2Fill
2 | ViewDragHelper和RecyclerView的使用示例
3 |
4 |
5 | 
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/fast_new_left_adding.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-hdpi/fast_new_left_adding.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiang111/DragView2Fill/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/number_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Feb 01 09:00:48 CST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bordors.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fast_adding.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fast_item_empty.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/test/java/com/jyuesong/dragview2fill/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.jyuesong.dragview2fill;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jyuesong/dragview2fill/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.jyuesong.dragview2fill;
2 |
3 | import android.support.v7.app.AppCompatActivity;
4 | import android.os.Bundle;
5 |
6 | import com.jyuesong.dragview2fill.dragview.DragViewGroup;
7 | import com.jyuesong.dragview2fill.dragview.RecyclerViewHelper;
8 |
9 | public class MainActivity extends AppCompatActivity implements RecyclerViewHelper.SizeChangedCallBack {
10 |
11 | DragViewGroup mDragViewGroup;
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | setContentView(R.layout.activity_main);
17 | mDragViewGroup = findViewById(R.id.fast_new_lianxi_view);
18 | mDragViewGroup.registerSizeChangeCallBack(this);
19 | }
20 |
21 | @Override
22 | public void size(int count) {
23 |
24 | }
25 |
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/jyuesong/dragview2fill/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.jyuesong.dragview2fill;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.jyuesong.dragview2fill", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fast_item_title.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jyuesong/dragview2fill/FastModel.java:
--------------------------------------------------------------------------------
1 | package com.jyuesong.dragview2fill;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by jiang on 29/01/2018.
7 | */
8 | public class FastModel implements Serializable{
9 |
10 | private int type;
11 | private int count;
12 | private boolean isAdding;
13 |
14 | public FastModel() {
15 | }
16 |
17 | public FastModel(int type, int count) {
18 | this.type = type;
19 | this.count = count;
20 | }
21 |
22 | public FastModel(boolean isAdding) {
23 | this.isAdding = isAdding;
24 | }
25 |
26 | public int getType() {
27 | return type;
28 | }
29 |
30 | public void setType(int type) {
31 | this.type = type;
32 | }
33 |
34 | public int getCount() {
35 | return count;
36 | }
37 |
38 | public void setCount(int count) {
39 | this.count = count;
40 | }
41 |
42 | public boolean isAdding() {
43 | return isAdding;
44 | }
45 |
46 | public void setAdding(boolean adding) {
47 | isAdding = adding;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | ### Android template
3 | # Built application files
4 | *.apk
5 | *.ap_
6 |
7 | # Files for the ART/Dalvik VM
8 | *.dex
9 |
10 | # Java class files
11 | *.class
12 |
13 | # Generated files
14 | bin/
15 | gen/
16 | out/
17 |
18 | # Gradle files
19 | .gradle/
20 | build/
21 |
22 | # Local configuration file (sdk path, etc)
23 | local.properties
24 |
25 | # Proguard folder generated by Eclipse
26 | proguard/
27 |
28 | # Log Files
29 | *.log
30 |
31 | # Android Studio Navigation editor temp files
32 | .navigation/
33 |
34 | # Android Studio captures folder
35 | captures/
36 |
37 | # IntelliJ
38 | *.iml
39 | .idea/workspace.xml
40 | .idea/tasks.xml
41 | .idea/gradle.xml
42 | .idea/dictionaries
43 | .idea/libraries
44 |
45 | # Keystore files
46 | # Uncomment the following line if you do not want to check your keystore files in.
47 | #*.jks
48 |
49 | # External native build folder generated in Android Studio 2.2 and later
50 | .externalNativeBuild
51 |
52 | # Google Services (e.g. APIs or Firebase)
53 | google-services.json
54 |
55 | # Freeline
56 | freeline.py
57 | freeline/
58 | freeline_project_description.json
59 |
60 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 26
5 | defaultConfig {
6 | applicationId "com.jyuesong.dragview2fill"
7 | minSdkVersion 15
8 | targetSdkVersion 26
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | implementation fileTree(dir: 'libs', include: ['*.jar'])
23 | implementation 'com.android.support:appcompat-v7:26.1.0'
24 | compile 'com.android.support:recyclerview-v7:26.1.0'
25 |
26 | implementation 'com.android.support.constraint:constraint-layout:1.0.2'
27 | testImplementation 'junit:junit:4.12'
28 | androidTestImplementation 'com.android.support.test:runner:1.0.1'
29 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
30 |
31 | compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
32 | compile 'io.reactivex.rxjava2:rxjava:2.0.1'
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fast_item_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
16 |
26 |
27 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fast_item_left2.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
16 |
26 |
27 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fast_item_left3.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
16 |
26 |
27 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 | ### Android template
11 | # Built application files
12 | *.apk
13 | *.ap_
14 |
15 | # Files for the ART/Dalvik VM
16 | *.dex
17 |
18 | # Java class files
19 | *.class
20 |
21 | # Generated files
22 | bin/
23 | gen/
24 | out/
25 |
26 | # Gradle files
27 | .gradle/
28 | build/
29 |
30 | # Local configuration file (sdk path, etc)
31 | local.properties
32 |
33 | # Proguard folder generated by Eclipse
34 | proguard/
35 |
36 | # Log Files
37 | *.log
38 |
39 | # Android Studio Navigation editor temp files
40 | .navigation/
41 |
42 | # Android Studio captures folder
43 | captures/
44 |
45 | # IntelliJ
46 | *.iml
47 | .idea/workspace.xml
48 | .idea/tasks.xml
49 | .idea/gradle.xml
50 | .idea/dictionaries
51 | .idea/libraries
52 |
53 | # Keystore files
54 | # Uncomment the following line if you do not want to check your keystore files in.
55 | #*.jks
56 |
57 | # External native build folder generated in Android Studio 2.2 and later
58 | .externalNativeBuild
59 |
60 | # Google Services (e.g. APIs or Firebase)
61 | google-services.json
62 |
63 | # Freeline
64 | freeline.py
65 | freeline/
66 | freeline_project_description.json
67 |
68 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jyuesong/dragview2fill/adapter/BaseAdapter.java:
--------------------------------------------------------------------------------
1 | package com.jyuesong.dragview2fill.adapter;
2 |
3 | import android.support.v7.widget.RecyclerView;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 | /**
9 | * Created by jiang on 16/8/29.
10 | */
11 | public abstract class BaseAdapter extends RecyclerView.Adapter {
12 |
13 |
14 | @Override
15 | public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
16 | return new BaseViewHolder(LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false));
17 | }
18 |
19 | @Override
20 | public void onBindViewHolder(final BaseViewHolder holder, final int position) {
21 |
22 |
23 | if (clickable()) {
24 | holder.getConvertView().setClickable(true);
25 | holder.getConvertView().setOnClickListener(new View.OnClickListener() {
26 | @Override
27 | public void onClick(View v) {
28 | onItemClick(v, position);
29 | }
30 | });
31 | }
32 |
33 | onBindView(holder, holder.getLayoutPosition());
34 |
35 | }
36 |
37 | public abstract void onBindView(BaseViewHolder holder, int position);
38 |
39 | @Override
40 | public int getItemViewType(int position) {
41 | return getLayoutID(position);
42 | }
43 |
44 |
45 | public abstract int getLayoutID(int position);
46 |
47 | public abstract boolean clickable();
48 |
49 | public void onItemClick(View v, int position) {
50 | }
51 |
52 |
53 |
54 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jyuesong/dragview2fill/dragview/LayoutHelper.java:
--------------------------------------------------------------------------------
1 | package com.jyuesong.dragview2fill.dragview;
2 |
3 | import android.util.SparseArray;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 |
7 |
8 | /**
9 | * Created by jiang on 29/01/2018.
10 | */
11 | public class LayoutHelper {
12 |
13 | public static SparseArray locations = new SparseArray<>();
14 |
15 |
16 | public static void layoutChild(ViewGroup parent, View child) {
17 |
18 | int tag = (int) child.getTag();
19 |
20 | if (tag == DragViewGroup.T_XUANZE) {
21 | ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) child.getLayoutParams();
22 | int childWidth = child.getMeasuredWidth();
23 | int childHeight = child.getMeasuredHeight();
24 | int[] locaition = new int[4];
25 | locaition[0] = parent.getPaddingLeft() + mlp.leftMargin;
26 | locaition[1] = parent.getPaddingTop() + mlp.topMargin;
27 | locaition[2] = childWidth + parent.getPaddingLeft()
28 | + mlp.leftMargin;
29 | locaition[3] = childHeight + parent.getPaddingTop() + mlp.topMargin;
30 | child.layout(locaition[0], locaition[1], locaition[2], locaition[3]);
31 | locations.append(DragViewGroup.T_XUANZE, locaition);
32 | } else if (tag == DragViewGroup.T_PANDUAN) {
33 | ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) child.getLayoutParams();
34 | int childWidth = child.getMeasuredWidth();
35 | int childHeight = child.getMeasuredHeight();
36 | int[] locaition = new int[4];
37 | locaition[0] = parent.getPaddingLeft() + mlp.leftMargin;
38 | locaition[1] = parent.getPaddingTop() + mlp.topMargin + locations.get(DragViewGroup.T_XUANZE)[3];
39 | locaition[2] = childWidth + parent.getPaddingLeft()
40 | + mlp.leftMargin;
41 | locaition[3] = childHeight + locaition[1];
42 | child.layout(locaition[0], locaition[1], locaition[2], locaition[3]);
43 | locations.append(DragViewGroup.T_PANDUAN, locaition);
44 | } else {
45 | ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) child.getLayoutParams();
46 | int childWidth = child.getMeasuredWidth();
47 | int childHeight = child.getMeasuredHeight();
48 | int[] locaition = new int[4];
49 | locaition[0] = parent.getPaddingLeft() + mlp.leftMargin;
50 | locaition[1] = parent.getPaddingTop() + mlp.topMargin + locations.get(DragViewGroup.T_PANDUAN)[3];
51 | locaition[2] = childWidth + parent.getPaddingLeft()
52 | + mlp.leftMargin;
53 | locaition[3] = childHeight + locaition[1];
54 | child.layout(locaition[0], locaition[1], locaition[2], locaition[3]);
55 | locations.append(DragViewGroup.T_ZHUGUAN, locaition);
56 | }
57 |
58 | }
59 |
60 | public static void layoutRecyclerView(ViewGroup parent, View child) {
61 |
62 | ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) child.getLayoutParams();
63 | int childWidth = child.getMeasuredWidth();
64 | int childHeight = child.getMeasuredHeight();
65 | child.layout(parent.getWidth() / 3, parent.getPaddingTop() + mlp.topMargin,
66 | parent.getWidth() / 3 + childWidth, parent.getPaddingTop() + mlp.topMargin + childHeight);
67 |
68 |
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fast_tixing_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
16 |
17 |
25 |
26 |
27 |
40 |
41 |
51 |
52 |
53 |
54 |
63 |
64 |
73 |
74 |
75 |
83 |
84 |
97 |
98 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jyuesong/dragview2fill/adapter/BaseViewHolder.java:
--------------------------------------------------------------------------------
1 | /**
2 | * created by jiang, 12/3/15
3 | * Copyright (c) 2015, jyuesong@gmail.com All Rights Reserved.
4 | * * # #
5 | * # _oo0oo_ #
6 | * # o8888888o #
7 | * # 88" . "88 #
8 | * # (| -_- |) #
9 | * # 0\ = /0 #
10 | * # ___/`---'\___ #
11 | * # .' \\| |# '. #
12 | * # / \\||| : |||# \ #
13 | * # / _||||| -:- |||||- \ #
14 | * # | | \\\ - #/ | | #
15 | * # | \_| ''\---/'' |_/ | #
16 | * # \ .-\__ '-' ___/-. / #
17 | * # ___'. .' /--.--\ `. .'___ #
18 | * # ."" '< `.___\_<|>_/___.' >' "". #
19 | * # | | : `- \`.;`\ _ /`;.`/ - ` : | | #
20 | * # \ \ `_. \_ __\ /__ _/ .-` / / #
21 | * # =====`-.____`.___ \_____/___.-`___.-'===== #
22 | * # `=---=' #
23 | * # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
24 | * # #
25 | * # 佛祖保佑 永无BUG #
26 | * # #
27 | */
28 |
29 | package com.jyuesong.dragview2fill.adapter;
30 |
31 | import android.graphics.drawable.Drawable;
32 | import android.support.annotation.IdRes;
33 | import android.support.annotation.IntDef;
34 | import android.support.v7.widget.RecyclerView;
35 | import android.util.SparseArray;
36 | import android.view.View;
37 | import android.widget.TextView;
38 |
39 | import java.lang.annotation.Retention;
40 | import java.lang.annotation.RetentionPolicy;
41 |
42 | /**
43 | * Created by jiang on 12/3/15.
44 | */
45 | public class BaseViewHolder extends RecyclerView.ViewHolder {
46 |
47 | protected final SparseArray mViews;
48 | protected View mConvertView;
49 |
50 |
51 | public BaseViewHolder(View itemView) {
52 | super(itemView);
53 | mViews = new SparseArray<>();
54 | mConvertView = itemView;
55 | }
56 |
57 |
58 | /**
59 | * 通过控件的Id获取对应的控件,如果没有则加入mViews,则从item根控件中查找并保存到mViews中
60 | *
61 | * @param viewId
62 | * @return
63 | */
64 | public T getView(@IdRes int viewId) {
65 | View view = mViews.get(viewId);
66 | if (view == null) {
67 | view = mConvertView.findViewById(viewId);
68 | mViews.put(viewId, view);
69 | }
70 | return (T) view;
71 | }
72 |
73 | public View getConvertView() {
74 | return mConvertView;
75 | }
76 |
77 | public BaseViewHolder setBgColor(@IdRes int resID, int color) {
78 | getView(resID).setBackgroundColor(color);
79 | return this;
80 | }
81 |
82 | public BaseViewHolder setBgDrawable(@IdRes int resID, Drawable drawable) {
83 | getView(resID).setBackground(drawable);
84 | return this;
85 |
86 | }
87 |
88 | public BaseViewHolder setText(@IdRes int resID, String text) {
89 | ((TextView) getView(resID)).setText(text);
90 | return this;
91 | }
92 |
93 | public BaseViewHolder setTextSize(@IdRes int resID, int spSize) {
94 | ((TextView) getView(resID)).setTextSize(spSize);
95 | return this;
96 | }
97 |
98 | public BaseViewHolder setVisibility(@IdRes int resID, @Visibility int visibility) {
99 | switch (visibility) {
100 | case VISIBLE:
101 | getView(resID).setVisibility(View.VISIBLE);
102 | break;
103 | case INVISIBLE:
104 | getView(resID).setVisibility(View.INVISIBLE);
105 | break;
106 | case GONE:
107 | getView(resID).setVisibility(View.GONE);
108 | break;
109 |
110 | }
111 | return this;
112 |
113 | }
114 |
115 | public BaseViewHolder setTextColor(int id, int textColor) {
116 | ((TextView) getView(id)).setTextColor(textColor);
117 | return this;
118 | }
119 |
120 |
121 | @IntDef({VISIBLE, INVISIBLE, GONE})
122 | @Retention(RetentionPolicy.SOURCE)
123 | public @interface Visibility {
124 | }
125 |
126 | public static final int VISIBLE = 0x00000000;
127 | public static final int INVISIBLE = 0x00000004;
128 |
129 | public static final int GONE = 0x00000008;
130 |
131 |
132 | }
133 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
11 |
16 |
21 |
26 |
31 |
36 |
41 |
46 |
51 |
56 |
61 |
66 |
71 |
76 |
81 |
86 |
91 |
96 |
101 |
106 |
111 |
116 |
121 |
126 |
131 |
136 |
141 |
146 |
151 |
156 |
161 |
166 |
171 |
172 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 | Spelling
111 |
112 |
113 |
114 |
115 | Spelling
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 | $USER_HOME$/.subversion
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 | 1.8
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jyuesong/dragview2fill/dragview/DragViewGroup.java:
--------------------------------------------------------------------------------
1 | package com.jyuesong.dragview2fill.dragview;
2 |
3 | import android.content.Context;
4 | import android.content.res.Resources;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.graphics.Rect;
9 | import android.support.v4.widget.ViewDragHelper;
10 | import android.support.v7.widget.RecyclerView;
11 | import android.util.AttributeSet;
12 | import android.util.DisplayMetrics;
13 | import android.view.LayoutInflater;
14 | import android.view.MotionEvent;
15 | import android.view.View;
16 | import android.view.ViewGroup;
17 |
18 | import com.jyuesong.dragview2fill.FastModel;
19 | import com.jyuesong.dragview2fill.R;
20 |
21 | import java.util.List;
22 | import java.util.concurrent.TimeUnit;
23 |
24 | import io.reactivex.android.schedulers.AndroidSchedulers;
25 | import io.reactivex.functions.Consumer;
26 | import io.reactivex.schedulers.Schedulers;
27 | import io.reactivex.subjects.PublishSubject;
28 |
29 | /**
30 | * Created by jiang on 29/01/2018.
31 | */
32 | public class DragViewGroup extends ViewGroup {
33 |
34 | private static final String TAG = "DragViewGroup";
35 |
36 | public static final int DEFAULT = -0x110011;
37 |
38 | private View[] view1 = new View[2];
39 | private View[] view2 = new View[2];
40 | private View[] view3 = new View[2];
41 |
42 | private Rect[] mBorders = new Rect[2];
43 | private ViewDragHelper mViewDragHelper;
44 |
45 | private Paint mBgPaint;
46 |
47 | private LayoutInflater mLayoutInflater;
48 | private int mWidth;
49 | private int mHeight;
50 |
51 | private RecyclerViewHelper mRecyclerViewHelper;
52 | private boolean dragEnable = true;
53 | private PublishSubject mPublishSubject;
54 |
55 |
56 | public DragViewGroup(Context context) {
57 | this(context, null);
58 | }
59 |
60 | public DragViewGroup(Context context, AttributeSet attrs) {
61 | this(context, attrs, 0);
62 | }
63 |
64 | public DragViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
65 | super(context, attrs, defStyleAttr);
66 | setWillNotDraw(false);
67 | mLayoutInflater = LayoutInflater.from(context);
68 | mRecyclerViewHelper = RecyclerViewHelper.create(this);
69 | initViews();
70 | }
71 |
72 |
73 | private void initViews() {
74 | initSize();
75 |
76 | mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
77 | mBgPaint.setStyle(Paint.Style.FILL);
78 | mViewDragHelper = ViewDragHelper.create(this, 1.0f, new CallBack());
79 |
80 | //可以直接通过布局文件inflate进来
81 | addView(mRecyclerViewHelper.generateRecyclerView());
82 | addView(view1[0] = createView1());
83 | addView(view2[0] = createView2());
84 | addView(view3[0] = createView3());
85 | addView(view1[1] = createView1());
86 | addView(view2[1] = createView2());
87 | addView(view3[1] = createView3());
88 |
89 | LayoutParams layoutParams = mRecyclerViewHelper.getRecyclerView().getLayoutParams();
90 | layoutParams.width = mWidth * 2 / 3;
91 | layoutParams.height = LayoutParams.MATCH_PARENT;
92 | mRecyclerViewHelper.getRecyclerView().setLayoutParams(layoutParams);
93 | mRecyclerViewHelper.init();
94 | }
95 |
96 | private void initSize() {
97 | Resources resources = this.getResources();
98 | DisplayMetrics dm = resources.getDisplayMetrics();
99 | mWidth = dm.widthPixels;
100 | mHeight = dm.heightPixels;
101 | }
102 |
103 | public void dragEnable(boolean can) {
104 | dragEnable = can;
105 | }
106 |
107 |
108 | private View createView2() {
109 | View view = mLayoutInflater.inflate(R.layout.fast_item_left2, this, false);
110 | LayoutParams layoutParams = view.getLayoutParams();
111 | layoutParams.width = mWidth / 3;
112 | view.setLayoutParams(layoutParams);
113 | view.setTag(T_PANDUAN);
114 | return view;
115 | }
116 |
117 |
118 | private View createView3() {
119 | View view = mLayoutInflater.inflate(R.layout.fast_item_left3, this, false);
120 | LayoutParams layoutParams = view.getLayoutParams();
121 | layoutParams.width = mWidth / 3;
122 | view.setLayoutParams(layoutParams);
123 | view.setTag(T_ZHUGUAN);
124 | return view;
125 | }
126 |
127 |
128 | private View createView1() {
129 | View view = mLayoutInflater.inflate(R.layout.fast_item_left, this, false);
130 | LayoutParams layoutParams = view.getLayoutParams();
131 | layoutParams.width = mWidth / 3;
132 | view.setLayoutParams(layoutParams);
133 | view.setTag(T_XUANZE);
134 | return view;
135 | }
136 |
137 | @Override
138 | protected LayoutParams generateDefaultLayoutParams() {
139 | return new MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
140 | }
141 |
142 | @Override
143 | protected LayoutParams generateLayoutParams(LayoutParams p) {
144 | return new MarginLayoutParams(p);
145 | }
146 |
147 | @Override
148 | public LayoutParams generateLayoutParams(AttributeSet attrs) {
149 | return new MarginLayoutParams(getContext(), attrs);
150 | }
151 |
152 | @Override
153 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
154 |
155 | if (getChildCount() < 0) return;
156 | for (int i = 0; i < getChildCount(); i++) {
157 | View child = getChildAt(i);
158 | measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
159 | // 测量逻辑不用管太多
160 | int childWidth;
161 | int childHeight;
162 | //直接强制写死宽高
163 | childWidth = MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(), MeasureSpec.EXACTLY);
164 | childHeight = MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(), MeasureSpec.EXACTLY);
165 | child.measure(childWidth, childHeight);
166 | }
167 |
168 |
169 | //这的宽高可根据需求自己写测量逻辑
170 | super.onMeasure(MeasureSpec.makeMeasureSpec(mWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(mHeight, MeasureSpec.EXACTLY));
171 | Rect rect1 = new Rect(getPaddingLeft(), getPaddingTop(), getPaddingLeft() + getMeasuredWidth() / 3, getPaddingTop() + getMeasuredHeight());
172 | mBorders[0] = rect1;
173 | Rect rect2 = new Rect(getPaddingLeft() + getMeasuredWidth() / 3, getPaddingTop(), getPaddingLeft() + getMeasuredWidth(), getPaddingTop() + getMeasuredHeight());
174 | mBorders[1] = rect2;
175 | }
176 |
177 | @Override
178 | protected void onLayout(boolean changed, int l, int t, int r, int b) {
179 | if (getChildCount() <= 0) return;
180 | for (int i = 0; i < getChildCount(); i++) {
181 | View view = getChildAt(i);
182 | if (view instanceof RecyclerView) {
183 | //recyclerview
184 | LayoutHelper.layoutRecyclerView(this, view);
185 | } else if (view instanceof View) {
186 | if (mDragView != null && mDragView == view && mDragLocation[0] != DEFAULT && mDragLocation[1] != DEFAULT) {
187 | view.layout(mDragLocation[0], mDragLocation[1],
188 | view.getMeasuredWidth() + mDragLocation[0], view.getMeasuredHeight() + mDragLocation[1]);
189 | } else {
190 | LayoutHelper.layoutChild(this, view);
191 | }
192 | }
193 | }
194 |
195 |
196 | }
197 |
198 |
199 | @Override
200 | protected void onDraw(Canvas canvas) {
201 | super.onDraw(canvas);
202 | mBgPaint.setColor(Color.parseColor("#ffffff"));
203 | canvas.drawRect(mBorders[0], mBgPaint);
204 | mBgPaint.setColor(Color.parseColor("#f1f1f1"));
205 | canvas.drawRect(mBorders[1], mBgPaint);
206 | }
207 |
208 | @Override
209 | public boolean onInterceptTouchEvent(MotionEvent event) {
210 | return mViewDragHelper.shouldInterceptTouchEvent(event);
211 | }
212 |
213 | @Override
214 | public boolean onTouchEvent(MotionEvent event) {
215 | mViewDragHelper.processTouchEvent(event);
216 | return true;
217 | }
218 |
219 | public void registerSizeChangeCallBack(RecyclerViewHelper.SizeChangedCallBack sizeChangedCallBack) {
220 |
221 | if (sizeChangedCallBack != null && mRecyclerViewHelper != null) {
222 | mRecyclerViewHelper.setSizeChangedCallBack(sizeChangedCallBack);
223 | }
224 | }
225 |
226 | public List getTopicStructure() {
227 | if (mRecyclerViewHelper != null) {
228 | return mRecyclerViewHelper.mList;
229 | }
230 | return null;
231 | }
232 |
233 | public void fillData(List data) {
234 | if (mRecyclerViewHelper != null) {
235 | mRecyclerViewHelper.init(data);
236 | }
237 | }
238 |
239 |
240 | public class CallBack extends ViewDragHelper.Callback {
241 |
242 | @Override
243 | public boolean tryCaptureView(View child, int pointerId) {
244 | if (!dragEnable) return false;
245 | boolean can = canDrag(child);
246 | if (can) isDraging = true;
247 | mDragView = child;
248 | mRecyclerViewHelper.reset();
249 | if (can) {
250 | child.setBackgroundColor(Color.parseColor("#f7f7f9"));
251 | bringChildToFront(child);
252 | initRxSubject();
253 | }
254 | mDragLocation[0] = DEFAULT;
255 | mDragLocation[1] = DEFAULT;
256 | return can;
257 | }
258 |
259 | @Override
260 | public int clampViewPositionHorizontal(View child, int left, int dx) {
261 | final int leftBound = getPaddingLeft();
262 | final int rightBound = getWidth() - leftBound - child.getMeasuredWidth();
263 |
264 | final int newLeft = Math.min(Math.max(left, leftBound), rightBound);
265 |
266 | return newLeft;
267 | }
268 |
269 | @Override
270 | public int clampViewPositionVertical(View child, int top, int dy) {
271 | return top;
272 | }
273 |
274 | @Override
275 | public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
276 | mDragLocation[0] = left;
277 | mDragLocation[1] = top;
278 |
279 | if (!isDraging) return;
280 |
281 | if (left < (getWidth() / 3 - changedView.getWidth() / 2)) {
282 | mRecyclerViewHelper.cancel();
283 | } else {
284 | int[] ints = new int[4];
285 | ints[0] = left;
286 | ints[1] = top;
287 | ints[2] = changedView.getBottom();
288 | ints[3] = (int) changedView.getTag();
289 | if (mPublishSubject != null) {
290 | mPublishSubject.onNext(ints);
291 | } else {
292 | mRecyclerViewHelper.draging(ints);
293 | }
294 | }
295 |
296 | }
297 |
298 | @Override
299 | public void onViewReleased(View releasedChild, float xvel, float yvel) {
300 | isDraging = false;
301 | if (mPublishSubject != null)
302 | mPublishSubject.onComplete();
303 | if (releasedChild.getTag() != null) {
304 | int[] ints = new int[4];
305 | ints[0] = releasedChild.getLeft();
306 | ints[1] = releasedChild.getTop();
307 | ints[2] = releasedChild.getBottom();
308 | ints[3] = (int) releasedChild.getTag();
309 | if (ints[0] < (getWidth() / 3 - releasedChild.getWidth() / 2)) {
310 | mRecyclerViewHelper.cancel();
311 | } else {
312 | mRecyclerViewHelper.dragFinish(ints[3]);
313 | }
314 | int tag = (int) releasedChild.getTag();
315 | if (mDragView != null) {
316 | mDragView.setVisibility(INVISIBLE);
317 | }
318 |
319 | mViewDragHelper.settleCapturedViewAt(LayoutHelper.locations.get(tag)[0], LayoutHelper.locations.get(tag)[1]);
320 | invalidate();
321 | }
322 | }
323 | }
324 |
325 | private void initRxSubject() {
326 |
327 | //通过throttleLast做延迟,防止拖动的时候闪的太快
328 | mPublishSubject = PublishSubject.create();
329 | mPublishSubject.throttleLast(300, TimeUnit.MILLISECONDS)
330 | .subscribeOn(Schedulers.io())
331 | .observeOn(AndroidSchedulers.mainThread())
332 | .subscribe(new Consumer() {
333 | @Override
334 | public void accept(int[] ints) throws Exception {
335 | if (mRecyclerViewHelper != null)
336 | mRecyclerViewHelper.draging(ints);
337 |
338 | }
339 | });
340 | }
341 |
342 | private View mDragView;
343 | public static boolean isDraging; //是否正在拖拽
344 | private int[] mDragLocation = new int[2];
345 |
346 | @Override
347 | public void computeScroll() {
348 | if (mViewDragHelper.continueSettling(true)) {
349 | invalidate();
350 | } else {
351 | if (mDragView != null && mDragView.getVisibility() != View.VISIBLE) {
352 | mDragView.setVisibility(VISIBLE);
353 | mDragView.setBackgroundColor(Color.parseColor("#ffffff"));
354 | if (mRecyclerViewHelper != null) {
355 | mRecyclerViewHelper.cancel();
356 | }
357 | }
358 | }
359 | }
360 |
361 | private boolean canDrag(View child) {
362 |
363 | if (child == view1[1]) return true;
364 | if (child == view2[1]) return true;
365 | if (child == view3[1]) return true;
366 | return false;
367 | }
368 |
369 | public String getSubjectTitle() {
370 | if (mRecyclerViewHelper != null) {
371 | return mRecyclerViewHelper.mSubjectTitle;
372 | }
373 | return RecyclerViewHelper.getSubjectTitle();
374 | }
375 |
376 |
377 | //必须从0开始
378 | public static final int T_XUANZE = 0;
379 | public static final int T_PANDUAN = 1;
380 | public static final int T_ZHUGUAN = 2;
381 | public static final int T_TITLE = 3;
382 | public static final int T_EMPTY = 4;
383 |
384 |
385 | }
386 |
--------------------------------------------------------------------------------
/app/src/main/java/com/jyuesong/dragview2fill/dragview/RecyclerViewHelper.java:
--------------------------------------------------------------------------------
1 | package com.jyuesong.dragview2fill.dragview;
2 |
3 | import android.app.AlertDialog;
4 | import android.content.DialogInterface;
5 | import android.graphics.Color;
6 | import android.support.v4.content.ContextCompat;
7 | import android.support.v7.widget.LinearLayoutManager;
8 | import android.support.v7.widget.RecyclerView;
9 | import android.support.v7.widget.helper.ItemTouchHelper;
10 | import android.text.Editable;
11 | import android.text.InputFilter;
12 | import android.text.TextUtils;
13 | import android.view.View;
14 | import android.view.ViewGroup;
15 | import android.view.inputmethod.EditorInfo;
16 | import android.widget.EditText;
17 | import android.widget.ImageView;
18 | import android.widget.LinearLayout;
19 | import android.widget.TextView;
20 | import android.widget.Toast;
21 |
22 | import com.jyuesong.dragview2fill.FastModel;
23 | import com.jyuesong.dragview2fill.R;
24 | import com.jyuesong.dragview2fill.adapter.BaseAdapter;
25 | import com.jyuesong.dragview2fill.adapter.BaseViewHolder;
26 |
27 | import java.text.SimpleDateFormat;
28 | import java.util.ArrayList;
29 | import java.util.Collections;
30 | import java.util.Date;
31 | import java.util.List;
32 |
33 | /**
34 | * Created by jiang on 29/01/2018.
35 | */
36 | public class RecyclerViewHelper extends ItemTouchHelper.Callback {
37 |
38 |
39 | private ViewGroup mParent;
40 | private RecyclerView mRecyclerView;
41 | private ItemTouchHelper mItemTouchHelper;
42 | public static final int MAX_COUNT = 50; //题数最大值
43 | public static final int MAX_SUBJECT_COUNT = 10; //可拖动的最大个数
44 | public SizeChangedCallBack mSizeChangedCallBack;
45 | protected String mSubjectTitle = getSubjectTitle();
46 |
47 | public void setSizeChangedCallBack(SizeChangedCallBack sizeChangedCallBack) {
48 | mSizeChangedCallBack = sizeChangedCallBack;
49 | }
50 |
51 | public RecyclerViewHelper(ViewGroup parent) {
52 | this.mParent = parent;
53 |
54 | }
55 |
56 | public static RecyclerViewHelper create(ViewGroup parent) {
57 | return new RecyclerViewHelper(parent);
58 | }
59 |
60 | public RecyclerView generateRecyclerView() {
61 | mRecyclerView = new RecyclerView(mParent.getContext());
62 | mItemTouchHelper = new ItemTouchHelper(this);
63 | mItemTouchHelper.attachToRecyclerView(mRecyclerView);
64 | return mRecyclerView;
65 | }
66 |
67 | public RecyclerView getRecyclerView() {
68 | return mRecyclerView;
69 | }
70 |
71 | private int lastPosition = -1;
72 | private boolean dealing = false;
73 |
74 | public List mList = new ArrayList<>();
75 |
76 |
77 | public void init(List lianXiTiXingModels) {
78 | mList.clear();
79 | mList.add(new FastModel(DragViewGroup.T_TITLE, 0));
80 | if (lianXiTiXingModels == null) {
81 | mList.add(new FastModel(DragViewGroup.T_EMPTY, 0));
82 | } else {
83 | mList.addAll(lianXiTiXingModels);
84 | }
85 |
86 | mRecyclerView.setLayoutManager(new LinearLayoutManager(mParent.getContext(), LinearLayoutManager.VERTICAL, false));
87 | mRecyclerView.setAdapter(new MyAdapter());
88 | }
89 |
90 | public void init() {
91 | init(null);
92 |
93 |
94 | }
95 |
96 | public void adding(int pos) {
97 | if (lastPosition == pos) return;
98 | if (pos < 0) return;
99 | cancel();
100 | mList.add(pos, new FastModel(true));
101 | lastPosition = pos;
102 | mRecyclerView.getAdapter().notifyItemInserted(pos);
103 |
104 | }
105 |
106 | public void dragFinish(int tag) {
107 |
108 | int bestPosition = lastPosition;
109 | cancel();
110 | if (bestPosition >= 0) {
111 | mList.add(bestPosition, new FastModel(tag, 1));
112 | mRecyclerView.getAdapter().notifyItemInserted(bestPosition);
113 | if (mSizeChangedCallBack != null) {
114 | mSizeChangedCallBack.size(mList.size() - 1);
115 | }
116 | }
117 | reset();
118 | if (mList.size() > MAX_SUBJECT_COUNT) {
119 | msg("题型最多添加" + MAX_SUBJECT_COUNT + "个");
120 | }
121 | }
122 |
123 | private void removeAddingItem() {
124 | for (int i = 0; i < mList.size(); i++) {
125 | if (mList.get(i).isAdding()) {
126 | mList.remove(i);
127 | i--;
128 | }
129 |
130 | }
131 | }
132 |
133 | public void cancel() {
134 | lastPosition = -1;
135 | if (mList.size() == 2 && mList.get(1).getType() == DragViewGroup.T_EMPTY) mList.remove(1);
136 | removeAddingItem();
137 | mRecyclerView.getAdapter().notifyDataSetChanged();
138 | }
139 |
140 | public void reset() {
141 | dealing = false;
142 | lastPosition = -1;
143 |
144 | }
145 |
146 | public static String getSubjectTitle() {
147 | return "课堂练习 " + new SimpleDateFormat("yyyyMMdd HH:mm").format(new Date());
148 |
149 | }
150 |
151 | public void draging(int[] ints) {
152 |
153 | if (dealing) return;
154 | dealing = true;
155 | //只需要知道顶部坐标,来判断要不要添加,添加到哪
156 | int top = ints[1];
157 | int bottom = ints[2];
158 | int tag = ints[3];
159 |
160 | //根据position一个一个找到一个位置,位置的顶部在top上面,然后下一个位置的底部在top的下面
161 | int positions = findBestPosition(top, bottom, mRecyclerView);
162 | if (positions == 0) {
163 | positions = 1;
164 | }
165 | if (mList.size() == 1 && mList.get(0).isAdding()) return;
166 | adding(positions);
167 | dealing = false;
168 | }
169 |
170 | private int findBestPosition(int top, int bottom, RecyclerView recyclerView) {
171 | if (mList == null || mList.size() == 0) return 0;
172 | LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
173 |
174 | int position = linearLayoutManager.findFirstVisibleItemPosition();
175 |
176 |
177 | View view = linearLayoutManager.findViewByPosition(position);
178 |
179 | if (view == null) return -1;
180 | if (view.getTop() > top && view.getBottom() > bottom) {
181 | return position;
182 | }
183 | for (int i = position; i < mList.size() - 1; i++) {
184 | View view1 = linearLayoutManager.findViewByPosition(i);
185 | View view2 = linearLayoutManager.findViewByPosition(i + 1);
186 | if (view1 == null || view2 == null) {
187 | return -1;
188 | }
189 | int tempTop = view1.getTop();
190 | int tempBottom = view2.getBottom();
191 | if (tempBottom > top && tempTop < top) {
192 | return i + 1;
193 | }
194 | }
195 | return position + 1;
196 | }
197 |
198 | private static final String TAG = "RecyclerViewHelper";
199 |
200 | @Override
201 | public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
202 | int position = viewHolder.getAdapterPosition();
203 | if (mList.get(position).getType() == DragViewGroup.T_TITLE) return 0;
204 | if (mList.get(position).getType() == DragViewGroup.T_EMPTY)
205 | return makeMovementFlags(ItemTouchHelper.UP |
206 | ItemTouchHelper.DOWN, 0);
207 | if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
208 | final int dragFlag = ItemTouchHelper.UP |
209 | ItemTouchHelper.DOWN | ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT;
210 | int swipeFlag = ItemTouchHelper.START;
211 | return makeMovementFlags(dragFlag, swipeFlag);
212 | }
213 | return 0;
214 | }
215 |
216 | @Override
217 | public boolean isItemViewSwipeEnabled() {
218 | return true;
219 | }
220 |
221 | @Override
222 | public boolean isLongPressDragEnabled() {
223 | return true;
224 | }
225 |
226 | @Override
227 | public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
228 | int fromPos = viewHolder.getAdapterPosition();
229 | int toPos = target.getAdapterPosition();
230 | if (toPos == 0) toPos = 1;
231 | if (fromPos == toPos) return true;
232 | if (fromPos < toPos) {
233 | for (int i = fromPos; i < toPos; i++) {
234 | Collections.swap(mList, i, i + 1);
235 | }
236 | } else {
237 | for (int i = fromPos; i > toPos; i--) {
238 | Collections.swap(mList, i, i - 1);
239 | }
240 | }
241 |
242 | recyclerView.getAdapter().notifyItemMoved(fromPos, toPos);
243 | if (mSizeChangedCallBack != null) {
244 | mSizeChangedCallBack.size(mList.size() - 1);
245 | }
246 | return true;
247 | }
248 |
249 | @Override
250 | public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
251 | int position = viewHolder.getAdapterPosition();
252 | if (mList.get(position).getType() == DragViewGroup.T_TITLE) return;
253 | deleteItem(position, true);
254 |
255 | }
256 |
257 |
258 | public class MyAdapter extends BaseAdapter {
259 | @Override
260 | public void onBindView(final BaseViewHolder holder, final int position) {
261 | if (mList.get(position).isAdding()) return;
262 |
263 | int type = mList.get(position).getType();
264 | if (type == DragViewGroup.T_TITLE) {
265 | holder.getConvertView().setBackgroundColor(Color.parseColor("#ffffff"));
266 | holder.setText(R.id.fast_new_title, mSubjectTitle);
267 |
268 | } else if (type == DragViewGroup.T_EMPTY) {
269 | } else {
270 | holder.getConvertView().setBackgroundColor(Color.parseColor("#f7f7f9"));
271 | final int countValue = mList.get(position).getCount();
272 | String title = getTitleByType(type);
273 | ImageView delete = holder.getView(R.id.fast_new_delete);
274 | delete.setClickable(true);
275 | delete.setOnClickListener(new View.OnClickListener() {
276 | @Override
277 | public void onClick(View v) {
278 | deleteItem(position, false);
279 |
280 | }
281 | });
282 | holder.setText(R.id.title, title);
283 | ImageView imageView = holder.getView(R.id.fast_item_icon);
284 | int drawable = getDrawableByType(type);
285 | imageView.setImageDrawable(ContextCompat.getDrawable(mParent.getContext(), drawable));
286 | TextView count = holder.getView(R.id.fast_count);
287 | count.setText(countValue + "");
288 | count.setClickable(true);
289 | count.setOnClickListener(new View.OnClickListener() {
290 | @Override
291 | public void onClick(View v) {
292 | itemCountClicked(position, mList.get(position).getCount());
293 | }
294 | });
295 |
296 | ImageView add = holder.getView(R.id.fast_add);
297 | ImageView reduce = holder.getView(R.id.fast_reduce);
298 | if (countValue >= MAX_COUNT) {
299 | add.setVisibility(View.GONE);
300 | } else {
301 | add.setVisibility(View.VISIBLE);
302 | add.setClickable(true);
303 | add.setOnClickListener(new View.OnClickListener() {
304 | @Override
305 | public void onClick(View v) {
306 | mList.get(position).setCount(countValue + 1);
307 | notifyItemChanged(position);
308 | }
309 | });
310 | }
311 | if (countValue <= 1) {
312 | reduce.setVisibility(View.GONE);
313 | } else {
314 | reduce.setVisibility(View.VISIBLE);
315 | reduce.setClickable(true);
316 | reduce.setOnClickListener(new View.OnClickListener() {
317 | @Override
318 | public void onClick(View v) {
319 | mList.get(position).setCount(countValue - 1);
320 | notifyItemChanged(position);
321 | }
322 | });
323 | }
324 |
325 | }
326 |
327 | }
328 |
329 | @Override
330 | public int getLayoutID(int position) {
331 | if (mList.get(position).isAdding()) {
332 | return R.layout.fast_adding;
333 |
334 | }
335 | if (mList.get(position).getType() == DragViewGroup.T_TITLE)
336 | return R.layout.fast_item_title;
337 | if (mList.get(position).getType() == DragViewGroup.T_EMPTY)
338 | return R.layout.fast_item_empty;
339 | return R.layout.fast_tixing_item;
340 | }
341 |
342 | @Override
343 | public boolean clickable() {
344 | return false;
345 | }
346 |
347 | @Override
348 | public int getItemCount() {
349 | return mList.size();
350 | }
351 | }
352 |
353 | private void deleteItem(int position, boolean anim) {
354 | mList.remove(position);
355 | if (anim) {
356 | mRecyclerView.getAdapter().notifyItemRemoved(position);
357 | }
358 | if (mList.size() == 1) {
359 | mList.add(new FastModel(DragViewGroup.T_EMPTY, 0));
360 | mRecyclerView.getAdapter().notifyItemInserted(1);
361 |
362 | }
363 | //以后可以用 notifyItemRangeChanged这个方法来提高效率
364 | // if (!anim) {
365 | mRecyclerView.getAdapter().notifyDataSetChanged();
366 | // }
367 | if (mSizeChangedCallBack != null) {
368 | if (mList.size() == 2 && mList.get(1).getType() == DragViewGroup.T_EMPTY) {
369 | mSizeChangedCallBack.size(0);
370 | } else {
371 | mSizeChangedCallBack.size(mList.size() - 1);
372 | }
373 | }
374 | }
375 |
376 | private void itemCountClicked(final int position, int count) {
377 | final EditText input = new EditText(mParent.getContext());
378 | input.setInputType(EditorInfo.TYPE_CLASS_NUMBER);
379 | input.setFilters(new InputFilter[]{new InputFilter.LengthFilter(3)});
380 |
381 | // input.setImeOptions(EditorInfo.IME_ACTION_DONE);
382 | LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
383 | LinearLayout.LayoutParams.MATCH_PARENT,
384 | LinearLayout.LayoutParams.MATCH_PARENT);
385 | input.setLayoutParams(lp);
386 | input.setText(count + "");
387 |
388 | final AlertDialog alertDialog = new AlertDialog.Builder(mParent.getContext())
389 | .setView(input)
390 | .setCancelable(false)
391 | .setTitle("请设置题数")
392 | .setPositiveButton("确定", new DialogInterface.OnClickListener() {
393 | @Override
394 | public void onClick(DialogInterface dialog, int which) {
395 |
396 | }
397 | }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
398 | @Override
399 | public void onClick(DialogInterface dialog, int which) {
400 | dialog.dismiss();
401 |
402 | }
403 | }).create();
404 | alertDialog.setCanceledOnTouchOutside(false);
405 | alertDialog.show();
406 | alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
407 | @Override
408 | public void onClick(View v) {
409 | Editable editable = input.getText();
410 | if (TextUtils.isEmpty(editable)) {
411 | msg("题数不能为空");
412 | return;
413 | }
414 | try {
415 | int result = Integer.valueOf(editable.toString());
416 | if (result < 0) {
417 | msg("题数不能小于0");
418 | return;
419 | }
420 | if (result == 0) {
421 | msg("题数不能为0");
422 | return;
423 | }
424 | if (result > MAX_COUNT) {
425 | msg("题数不能超过" + MAX_COUNT);
426 | return;
427 | }
428 | mList.get(position).setCount(result);
429 | alertDialog.dismiss();
430 | mRecyclerView.getAdapter().notifyItemChanged(position);
431 | } catch (Exception e1) {
432 | msg("题数不合法");
433 |
434 |
435 | }
436 |
437 | }
438 | });
439 |
440 | }
441 |
442 | private void msg(String s) {
443 | Toast.makeText(mParent.getContext(), s, Toast.LENGTH_SHORT).show();
444 | }
445 |
446 | private int getDrawableByType(int type) {
447 | switch (type) {
448 | case DragViewGroup.T_PANDUAN:
449 | return R.mipmap.fast_panduan_icon;
450 |
451 | case DragViewGroup.T_XUANZE:
452 | return R.mipmap.fast_xuanze_icon;
453 |
454 | case DragViewGroup.T_ZHUGUAN:
455 | return R.mipmap.fast_zhuguan_icon;
456 | }
457 | return R.mipmap.fast_zhuguan_icon;
458 | }
459 |
460 | private String getTitleByType(int type) {
461 | switch (type) {
462 | case DragViewGroup.T_PANDUAN:
463 | return "判断题";
464 |
465 | case DragViewGroup.T_XUANZE:
466 | return "选择题";
467 |
468 | case DragViewGroup.T_ZHUGUAN:
469 | return "主观题";
470 | }
471 | return "大题";
472 | }
473 |
474 | public interface SizeChangedCallBack {
475 | void size(int count);
476 |
477 | }
478 | }
479 |
--------------------------------------------------------------------------------