Skip to content

Commit

Permalink
-A
Browse files Browse the repository at this point in the history
  • Loading branch information
bocq committed Nov 22, 2016
1 parent b7ce9e1 commit d5c797c
Show file tree
Hide file tree
Showing 52 changed files with 1,267 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild
22 changes: 22 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
jcenter()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}
1 change: 1 addition & 0 deletions dragrecyclerview/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
32 changes: 32 additions & 0 deletions dragrecyclerview/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
apply plugin: 'com.android.library'

android {
compileSdkVersion 24
buildToolsVersion "24.0.3"

defaultConfig {
minSdkVersion 15
targetSdkVersion 24
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(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
testCompile 'junit:junit:4.12'
compile 'com.android.support:recyclerview-v7:25.0.1'
}
17 changes: 17 additions & 0 deletions dragrecyclerview/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in D:\android\sdk24/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 name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package cn.cyan.dragrecyclerview;

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("cn.cyan.dragrecyclerview.test", appContext.getPackageName());
}
}
9 changes: 9 additions & 0 deletions dragrecyclerview/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.cyan.dragrecyclerview">

<application android:allowBackup="true" android:label="@string/app_name"
android:supportsRtl="true">

</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
package cn.cyan.dragrecyclerview;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.support.annotation.Nullable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;

/**
* Desc : 可拖动recyclerView
* User : Cyan([email protected])
* New : 2016/9/21 14:27
*/
public class DragRecyclerView extends RecyclerView {

/* 适配器 */
private OnItemChangeListener adapter;
/* 是否可拖动 */
private boolean dragEnable;
/* 是否显示拖动动画 */
private boolean showDragAnimation;


public DragRecyclerView(Context context) {
super(context);
init(context, null);
}

public DragRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}

private void init(Context context, AttributeSet attrs) {
if (attrs != null) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.DragRecyclerView);
dragEnable = ta.getBoolean(R.styleable.DragRecyclerView_drag_enable, true);
showDragAnimation = ta.getBoolean(R.styleable.DragRecyclerView_show_drag_animation, true);
ta.recycle();
} else {
dragEnable = true;
showDragAnimation = true;
}
}

///////////////////////////////////////////////////////////////////////////
// 拖动监听
///////////////////////////////////////////////////////////////////////////
ItemTouchHelper touchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
// 监听方向
if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
final int dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
return makeMovementFlags(dragFlag, 0);
} else {
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
final int swipeFlags = 0;
return makeMovementFlags(dragFlags, swipeFlags);
}
}

@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
// 原位置
int oldPosition = viewHolder.getAdapterPosition();
// 目标位置
int targetPosition = target.getAdapterPosition();
adapter.onItemMoved(oldPosition, targetPosition);
return false;
}

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
// 侧滑
}

@Override
public boolean isItemViewSwipeEnabled() {
return true;
}

@Override
public boolean isLongPressDragEnabled() {
// 禁用,使用自定义触摸监听
return false;
}

@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
//滑动时改变Item的透明度
final float alpha = 1 - Math.abs(dX) / (float) viewHolder.itemView.getWidth();
viewHolder.itemView.setAlpha(alpha);
viewHolder.itemView.setTranslationX(dX);
} else {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
}

@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
/** item已经被拽起(托起状态) */
// 设置背景
viewHolder.itemView.setBackgroundColor(Color.LTGRAY);
// 放大动画
if (showDragAnimation) zoomView(viewHolder.itemView);
}
super.onSelectedChanged(viewHolder, actionState);
}

@Override
public void clearView(RecyclerView recyclerView, ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
// 还原item的样式
viewHolder.itemView.setAlpha(1.0f);
viewHolder.itemView.setBackgroundColor(Color.WHITE);
// 缩放动画
if (showDragAnimation) revertView(viewHolder.itemView);
}

@Override
public boolean canDropOver(RecyclerView recyclerView, ViewHolder current, ViewHolder target) {
/** 被禁用的位置不会被挤兑 */
return adapter.onItemDrag(target.getAdapterPosition());
}
});

/* 放大动画 */
private ScaleAnimation zoomAnimation = new ScaleAnimation(1.0f, 1.1f, 1.0f, 1.1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
/* 还原动画 */
private ScaleAnimation revertAnimation = new ScaleAnimation(1.1f, 1.0f, 1.1f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

/**
* 放大
*
* @param v 视图
*/
private void zoomView(final View v) {
v.setAnimation(zoomAnimation);
// 动画执行完停留位置
zoomAnimation.setFillAfter(true);
// 动画持续时间
zoomAnimation.setDuration(200);
// 开始
zoomAnimation.start();
}

/**
* 还原
*
* @param v 视图
*/
private void revertView(final View v) {
v.setAnimation(revertAnimation);
// 动画执行完停留位置
revertAnimation.setFillAfter(true);
// 动画持续时间
revertAnimation.setDuration(400);
// 执行监听
revertAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}

@Override
public void onAnimationEnd(Animation animation) {
/** 动画结束后清除效果 */
v.clearAnimation();
}

@Override
public void onAnimationRepeat(Animation animation) {
}
});
// 开始
revertAnimation.start();
}

public DragRecyclerView setDragEnable(boolean dragEnable) {
this.dragEnable = dragEnable;
return this;
}

public DragRecyclerView setShowDragAnimation(boolean showDragAnimation) {
this.showDragAnimation = showDragAnimation;
return this;
}

public void setDragAdapter(OnItemChangeListener dragBaseAdapter) {
if (dragBaseAdapter instanceof Adapter) {
this.adapter = dragBaseAdapter;
if (dragEnable) {
touchHelper.attachToRecyclerView(this);
}
setAdapter((Adapter) adapter);
} else {
throw new IllegalArgumentException();
}
}

public void startDrag(ViewHolder viewHolder) {
touchHelper.startDrag(viewHolder);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package cn.cyan.dragrecyclerview;

/**
* Desc : item改变
* User : Cyan([email protected])
* New : 2016/9/28 8:41
*/
public interface OnItemChangeListener {

/* 是否可拖动 */
boolean onItemDrag(int position);

/* item移动 */
void onItemMoved(int form, int target);
}
8 changes: 8 additions & 0 deletions dragrecyclerview/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="DragRecyclerView">
<attr name="show_decoration" format="boolean"/>
<attr name="drag_enable" format="boolean"/>
<attr name="show_drag_animation" format="boolean"/>
</declare-styleable>
</resources>
3 changes: 3 additions & 0 deletions dragrecyclerview/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">DragRecyclerView</string>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package cn.cyan.dragrecyclerview;

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);
}
}
Loading

1 comment on commit d5c797c

@bocq
Copy link
Owner Author

@bocq bocq commented on d5c797c Jan 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

init

Please sign in to comment.