├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── 5DragRecyclerView ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── liaoinstan │ │ └── dragrecyclerview │ │ ├── activity │ │ └── MainActivity.java │ │ ├── adapter │ │ └── RecyclerAdapter.java │ │ ├── common │ │ ├── DividerGridItemDecoration.java │ │ └── DividerItemDecoration.java │ │ ├── entity │ │ └── Item.java │ │ ├── fragment │ │ ├── MainFragment.java │ │ ├── MyGridFragment.java │ │ └── MyListFragment.java │ │ ├── helper │ │ ├── MyItemTouchCallback.java │ │ └── OnRecyclerItemClickListener.java │ │ └── utils │ │ ├── ACache.java │ │ └── VibratorUtil.java │ └── res │ ├── drawable-xhdpi │ ├── item_img.png │ ├── takeout_ic_category_brand.png │ ├── takeout_ic_category_flower.png │ ├── takeout_ic_category_fruit.png │ ├── takeout_ic_category_medicine.png │ ├── takeout_ic_category_motorcycle.png │ ├── takeout_ic_category_public.png │ ├── takeout_ic_category_store.png │ ├── takeout_ic_category_sweet.png │ └── takeout_ic_more.png │ ├── layout │ ├── activity_main.xml │ ├── fragment_main.xml │ ├── item_grid.xml │ └── item_list.xml │ ├── menu │ └── menu_main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-v21 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── README.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | MyApplication -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /5DragRecyclerView/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /5DragRecyclerView/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.liaoinstan.dragrecyclerview" 9 | minSdkVersion 15 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.2.0' 26 | compile 'com.android.support:design:23.2.0' 27 | } 28 | -------------------------------------------------------------------------------- /5DragRecyclerView/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\LZ\develop\adt-eclipse\adt-bundle-windows-x86_64-20140702\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/java/com/liaoinstan/dragrecyclerview/activity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.liaoinstan.dragrecyclerview.activity; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.*; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.Toolbar; 7 | import android.view.View; 8 | 9 | import com.liaoinstan.dragrecyclerview.R; 10 | import com.liaoinstan.dragrecyclerview.fragment.MainFragment; 11 | import com.liaoinstan.dragrecyclerview.fragment.MyGridFragment; 12 | import com.liaoinstan.dragrecyclerview.fragment.MyListFragment; 13 | 14 | public class MainActivity extends AppCompatActivity implements View.OnClickListener{ 15 | 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | setContentView(R.layout.activity_main); 20 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 21 | setSupportActionBar(toolbar); 22 | 23 | if (savedInstanceState==null){ 24 | MainFragment mainFragment = new MainFragment(); 25 | getSupportFragmentManager().beginTransaction() 26 | .add(R.id.fragment,mainFragment) 27 | .commit(); 28 | } 29 | } 30 | 31 | @Override 32 | public void onClick(View v) { 33 | Fragment fragment = null; 34 | switch (v.getId()){ 35 | case R.id.list: 36 | fragment = new MyListFragment(); 37 | break; 38 | case R.id.grid: 39 | fragment = new MyGridFragment(); 40 | break; 41 | } 42 | getSupportFragmentManager().beginTransaction() 43 | .replace(R.id.fragment, fragment) 44 | .addToBackStack(null) 45 | .commit(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/java/com/liaoinstan/dragrecyclerview/adapter/RecyclerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.liaoinstan.dragrecyclerview.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.view.WindowManager; 9 | import android.widget.ImageView; 10 | import android.widget.TextView; 11 | 12 | import com.liaoinstan.dragrecyclerview.entity.Item; 13 | import com.liaoinstan.dragrecyclerview.R; 14 | import com.liaoinstan.dragrecyclerview.helper.MyItemTouchCallback; 15 | 16 | import java.util.Collections; 17 | import java.util.List; 18 | 19 | /** 20 | * Created by Administrator on 2016/4/12. 21 | */ 22 | public class RecyclerAdapter extends RecyclerView.Adapter implements MyItemTouchCallback.ItemTouchAdapter { 23 | 24 | private Context context; 25 | private int src; 26 | private List results; 27 | 28 | public RecyclerAdapter(int src,List results){ 29 | this.results = results; 30 | this.src = src; 31 | } 32 | 33 | @Override 34 | public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 35 | this.context = parent.getContext(); 36 | View itemView = LayoutInflater.from(parent.getContext()).inflate(src, parent, false); 37 | return new MyViewHolder(itemView); 38 | } 39 | 40 | @Override 41 | public void onBindViewHolder(final MyViewHolder holder, int position) { 42 | holder.imageView.setImageResource(results.get(position).getImg()); 43 | holder.textView.setText(results.get(position).getName()); 44 | } 45 | 46 | @Override 47 | public int getItemCount() { 48 | return results.size(); 49 | } 50 | 51 | @Override 52 | public void onMove(int fromPosition, int toPosition) { 53 | if (fromPosition==results.size()-1 || toPosition==results.size()-1){ 54 | return; 55 | } 56 | if (fromPosition < toPosition) { 57 | for (int i = fromPosition; i < toPosition; i++) { 58 | Collections.swap(results, i, i + 1); 59 | } 60 | } else { 61 | for (int i = fromPosition; i > toPosition; i--) { 62 | Collections.swap(results, i, i - 1); 63 | } 64 | } 65 | notifyItemMoved(fromPosition, toPosition); 66 | } 67 | 68 | @Override 69 | public void onSwiped(int position) { 70 | results.remove(position); 71 | notifyItemRemoved(position); 72 | } 73 | 74 | public class MyViewHolder extends RecyclerView.ViewHolder{ 75 | 76 | public TextView textView; 77 | public ImageView imageView; 78 | 79 | public MyViewHolder(View itemView) { 80 | super(itemView); 81 | WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 82 | int width = wm.getDefaultDisplay().getWidth(); 83 | ViewGroup.LayoutParams layoutParams = itemView.getLayoutParams(); 84 | layoutParams.height = width/4; 85 | itemView.setLayoutParams(layoutParams); 86 | textView = (TextView) itemView.findViewById(R.id.item_text); 87 | imageView = (ImageView) itemView.findViewById(R.id.item_img); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/java/com/liaoinstan/dragrecyclerview/common/DividerGridItemDecoration.java: -------------------------------------------------------------------------------- 1 | package com.liaoinstan.dragrecyclerview.common; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Canvas; 6 | import android.graphics.Color; 7 | import android.graphics.Rect; 8 | import android.graphics.drawable.ColorDrawable; 9 | import android.graphics.drawable.Drawable; 10 | import android.support.v7.widget.GridLayoutManager; 11 | import android.support.v7.widget.RecyclerView; 12 | import android.support.v7.widget.RecyclerView.LayoutManager; 13 | import android.support.v7.widget.RecyclerView.State; 14 | import android.support.v7.widget.StaggeredGridLayoutManager; 15 | import android.util.Log; 16 | import android.view.View; 17 | 18 | /** 19 | * @author zhy 20 | */ 21 | public class DividerGridItemDecoration extends RecyclerView.ItemDecoration { 22 | 23 | private static final int[] ATTRS = new int[]{android.R.attr.listDivider}; 24 | private Drawable mDivider; 25 | private int lineWidth = 1; 26 | 27 | public DividerGridItemDecoration(Context context) { 28 | final TypedArray a = context.obtainStyledAttributes(ATTRS); 29 | mDivider = a.getDrawable(0); 30 | a.recycle(); 31 | } 32 | 33 | public DividerGridItemDecoration(int color) { 34 | mDivider = new ColorDrawable(color); 35 | } 36 | 37 | public DividerGridItemDecoration() { 38 | this(Color.parseColor("#cccccc")); 39 | } 40 | 41 | @Override 42 | public void onDraw(Canvas c, RecyclerView parent, State state) { 43 | drawHorizontal(c, parent); 44 | drawVertical(c, parent); 45 | } 46 | 47 | private int getSpanCount(RecyclerView parent) { 48 | // 列数 49 | int spanCount = -1; 50 | LayoutManager layoutManager = parent.getLayoutManager(); 51 | if (layoutManager instanceof GridLayoutManager) { 52 | 53 | spanCount = ((GridLayoutManager) layoutManager).getSpanCount(); 54 | } else if (layoutManager instanceof StaggeredGridLayoutManager) { 55 | spanCount = ((StaggeredGridLayoutManager) layoutManager) 56 | .getSpanCount(); 57 | } 58 | return spanCount; 59 | } 60 | 61 | public void drawHorizontal(Canvas c, RecyclerView parent) { 62 | int childCount = parent.getChildCount(); 63 | for (int i = 0; i < childCount; i++) { 64 | final View child = parent.getChildAt(i); 65 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child 66 | .getLayoutParams(); 67 | final int left = child.getLeft() - params.leftMargin; 68 | final int right = child.getRight() + params.rightMargin 69 | + lineWidth; 70 | final int top = child.getBottom() + params.bottomMargin; 71 | final int bottom = top + lineWidth; 72 | mDivider.setBounds(left, top, right, bottom); 73 | mDivider.draw(c); 74 | } 75 | } 76 | 77 | public void drawVertical(Canvas c, RecyclerView parent) { 78 | final int childCount = parent.getChildCount(); 79 | for (int i = 0; i < childCount; i++) { 80 | final View child = parent.getChildAt(i); 81 | 82 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); 83 | final int top = child.getTop() - params.topMargin; 84 | final int bottom = child.getBottom() + params.bottomMargin; 85 | final int left = child.getRight() + params.rightMargin; 86 | final int right = left + lineWidth; 87 | 88 | mDivider.setBounds(left, top, right, bottom); 89 | mDivider.draw(c); 90 | } 91 | } 92 | 93 | private boolean isLastColum(RecyclerView parent, int pos, int spanCount, int childCount) { 94 | LayoutManager layoutManager = parent.getLayoutManager(); 95 | if (layoutManager instanceof GridLayoutManager) { 96 | if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边 97 | { 98 | return true; 99 | } 100 | } else if (layoutManager instanceof StaggeredGridLayoutManager) { 101 | int orientation = ((StaggeredGridLayoutManager) layoutManager) 102 | .getOrientation(); 103 | if (orientation == StaggeredGridLayoutManager.VERTICAL) { 104 | if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边 105 | { 106 | return true; 107 | } 108 | } else { 109 | childCount = childCount - childCount % spanCount; 110 | if (pos >= childCount)// 如果是最后一列,则不需要绘制右边 111 | return true; 112 | } 113 | } 114 | return false; 115 | } 116 | 117 | private boolean isLastRaw(RecyclerView parent, int pos, int spanCount, int childCount) { 118 | LayoutManager layoutManager = parent.getLayoutManager(); 119 | if (layoutManager instanceof GridLayoutManager) { 120 | childCount = childCount - childCount % spanCount; 121 | if (pos >= childCount)// 如果是最后一行,则不需要绘制底部 122 | return true; 123 | } else if (layoutManager instanceof StaggeredGridLayoutManager) { 124 | int orientation = ((StaggeredGridLayoutManager) layoutManager) 125 | .getOrientation(); 126 | // StaggeredGridLayoutManager 且纵向滚动 127 | if (orientation == StaggeredGridLayoutManager.VERTICAL) { 128 | childCount = childCount - childCount % spanCount; 129 | // 如果是最后一行,则不需要绘制底部 130 | if (pos >= childCount) 131 | return true; 132 | } else 133 | // StaggeredGridLayoutManager 且横向滚动 134 | { 135 | // 如果是最后一行,则不需要绘制底部 136 | if ((pos + 1) % spanCount == 0) { 137 | return true; 138 | } 139 | } 140 | } 141 | return false; 142 | } 143 | 144 | @Override 145 | public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) { 146 | // Log.e("liao", state.toString()); 147 | boolean b = state.willRunPredictiveAnimations(); 148 | int itemPosition = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition(); 149 | int spanCount = getSpanCount(parent); 150 | int childCount = parent.getAdapter().getItemCount(); 151 | // if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,则不需要绘制底部 152 | // { 153 | // outRect.set(0, 0, lineWidth, 0); 154 | // } 155 | // else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,则不需要绘制右边 156 | // { 157 | //// if (b){ 158 | //// outRect.set(0, 0, lineWidth, lineWidth); 159 | //// }else { 160 | // outRect.set(0, 0, 0, lineWidth); 161 | //// } 162 | // } 163 | // else { 164 | outRect.set(0, 0, lineWidth, lineWidth); 165 | // } 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/java/com/liaoinstan/dragrecyclerview/common/DividerItemDecoration.java: -------------------------------------------------------------------------------- 1 | package com.liaoinstan.dragrecyclerview.common; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Canvas; 6 | import android.graphics.Rect; 7 | import android.graphics.drawable.Drawable; 8 | import android.support.v7.widget.LinearLayoutManager; 9 | import android.support.v7.widget.RecyclerView; 10 | import android.view.View; 11 | 12 | /** 13 | * Created by Administrator on 2016/4/12. 14 | */ 15 | public class DividerItemDecoration extends RecyclerView.ItemDecoration { 16 | 17 | private static final int[] ATTRS = new int[]{ 18 | android.R.attr.listDivider 19 | }; 20 | 21 | public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL; 22 | 23 | public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL; 24 | 25 | private Drawable mDivider; 26 | 27 | private int mOrientation; 28 | 29 | public DividerItemDecoration(Context context, int orientation) { 30 | final TypedArray a = context.obtainStyledAttributes(ATTRS); 31 | mDivider = a.getDrawable(0); 32 | a.recycle(); 33 | setOrientation(orientation); 34 | } 35 | 36 | public void setOrientation(int orientation) { 37 | if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) { 38 | throw new IllegalArgumentException("invalid orientation"); 39 | } 40 | mOrientation = orientation; 41 | } 42 | 43 | @Override 44 | public void onDraw(Canvas c, RecyclerView parent) { 45 | // Log.v("recyclerview - itemdecoration", "onDraw()"); 46 | 47 | if (mOrientation == VERTICAL_LIST) { 48 | drawVertical(c, parent); 49 | } else { 50 | drawHorizontal(c, parent); 51 | } 52 | 53 | } 54 | 55 | 56 | public void drawVertical(Canvas c, RecyclerView parent) { 57 | final int left = parent.getPaddingLeft(); 58 | final int right = parent.getWidth() - parent.getPaddingRight(); 59 | 60 | final int childCount = parent.getChildCount(); 61 | for (int i = 0; i < childCount; i++) { 62 | final View child = parent.getChildAt(i); 63 | android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView(parent.getContext()); 64 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child 65 | .getLayoutParams(); 66 | final int top = child.getBottom() + params.bottomMargin; 67 | final int bottom = top + mDivider.getIntrinsicHeight(); 68 | mDivider.setBounds(left, top, right, bottom); 69 | mDivider.draw(c); 70 | } 71 | } 72 | 73 | public void drawHorizontal(Canvas c, RecyclerView parent) { 74 | final int top = parent.getPaddingTop(); 75 | final int bottom = parent.getHeight() - parent.getPaddingBottom(); 76 | 77 | final int childCount = parent.getChildCount(); 78 | for (int i = 0; i < childCount; i++) { 79 | final View child = parent.getChildAt(i); 80 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child 81 | .getLayoutParams(); 82 | final int left = child.getRight() + params.rightMargin; 83 | final int right = left + mDivider.getIntrinsicHeight(); 84 | mDivider.setBounds(left, top, right, bottom); 85 | mDivider.draw(c); 86 | } 87 | } 88 | 89 | @Override 90 | public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { 91 | if (mOrientation == VERTICAL_LIST) { 92 | outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); 93 | } else { 94 | outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/java/com/liaoinstan/dragrecyclerview/entity/Item.java: -------------------------------------------------------------------------------- 1 | package com.liaoinstan.dragrecyclerview.entity; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Created by Administrator on 2016/4/12. 7 | */ 8 | public class Item implements Serializable{ 9 | private int id; 10 | private String name; 11 | private int img; 12 | 13 | public Item(int id, String name, int img) { 14 | this.id = id; 15 | this.name = name; 16 | this.img = img; 17 | } 18 | 19 | public Item(String name, int img) { 20 | this.name = name; 21 | this.img = img; 22 | } 23 | 24 | public int getId() { 25 | return id; 26 | } 27 | 28 | public void setId(int id) { 29 | this.id = id; 30 | } 31 | 32 | public String getName() { 33 | return name; 34 | } 35 | 36 | public void setName(String name) { 37 | this.name = name; 38 | } 39 | 40 | public int getImg() { 41 | return img; 42 | } 43 | 44 | public void setImg(int img) { 45 | this.img = img; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/java/com/liaoinstan/dragrecyclerview/fragment/MainFragment.java: -------------------------------------------------------------------------------- 1 | package com.liaoinstan.dragrecyclerview.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.Fragment; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | import com.liaoinstan.dragrecyclerview.R; 11 | 12 | /** 13 | * Created by Administrator on 2016/4/12. 14 | */ 15 | public class MainFragment extends Fragment implements View.OnClickListener{ 16 | 17 | @Nullable 18 | @Override 19 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 20 | return inflater.inflate(R.layout.fragment_main,container,false); 21 | } 22 | 23 | @Override 24 | public void onViewCreated(View view, Bundle savedInstanceState) { 25 | super.onViewCreated(view, savedInstanceState); 26 | 27 | view.findViewById(R.id.list).setOnClickListener(this); 28 | view.findViewById(R.id.grid).setOnClickListener(this); 29 | } 30 | 31 | @Override 32 | public void onClick(View v) { 33 | ((View.OnClickListener)getActivity()).onClick(v); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/java/com/liaoinstan/dragrecyclerview/fragment/MyGridFragment.java: -------------------------------------------------------------------------------- 1 | package com.liaoinstan.dragrecyclerview.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.Fragment; 6 | import android.support.v7.widget.GridLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.support.v7.widget.helper.ItemTouchHelper; 9 | import android.view.LayoutInflater; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | import android.widget.Toast; 13 | 14 | import com.liaoinstan.dragrecyclerview.common.DividerGridItemDecoration; 15 | import com.liaoinstan.dragrecyclerview.entity.Item; 16 | import com.liaoinstan.dragrecyclerview.R; 17 | import com.liaoinstan.dragrecyclerview.adapter.RecyclerAdapter; 18 | import com.liaoinstan.dragrecyclerview.helper.MyItemTouchCallback; 19 | import com.liaoinstan.dragrecyclerview.helper.OnRecyclerItemClickListener; 20 | import com.liaoinstan.dragrecyclerview.utils.ACache; 21 | import com.liaoinstan.dragrecyclerview.utils.VibratorUtil; 22 | 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | 26 | /** 27 | * Created by Administrator on 2016/4/12. 28 | */ 29 | public class MyGridFragment extends Fragment implements MyItemTouchCallback.OnDragListener{ 30 | 31 | private List results = new ArrayList(); 32 | 33 | @Override 34 | public void onCreate(@Nullable Bundle savedInstanceState) { 35 | super.onCreate(savedInstanceState); 36 | //////////////////////////////////////////////////////// 37 | /////////初始化数据,如果缓存中有就使用缓存中的 38 | ArrayList items = (ArrayList) ACache.get(getActivity()).getAsObject("items"); 39 | if (items!=null) 40 | results.addAll(items); 41 | else { 42 | for (int i = 0; i < 3; i++) { 43 | results.add(new Item(i * 8 + 0, "收款", R.drawable.takeout_ic_category_brand)); 44 | results.add(new Item(i * 8 + 1, "转账", R.drawable.takeout_ic_category_flower)); 45 | results.add(new Item(i * 8 + 2, "余额宝", R.drawable.takeout_ic_category_fruit)); 46 | results.add(new Item(i * 8 + 3, "手机充值", R.drawable.takeout_ic_category_medicine)); 47 | results.add(new Item(i * 8 + 4, "医疗", R.drawable.takeout_ic_category_motorcycle)); 48 | results.add(new Item(i * 8 + 5, "彩票", R.drawable.takeout_ic_category_public)); 49 | results.add(new Item(i * 8 + 6, "电影", R.drawable.takeout_ic_category_store)); 50 | results.add(new Item(i * 8 + 7, "游戏", R.drawable.takeout_ic_category_sweet)); 51 | } 52 | } 53 | results.remove(results.size()-1); 54 | results.add(new Item(results.size(), "更多", R.drawable.takeout_ic_more)); 55 | //////////////////////////////////////////////////////// 56 | } 57 | 58 | @Nullable 59 | @Override 60 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 61 | return new RecyclerView(container.getContext()); 62 | } 63 | 64 | private RecyclerView recyclerView; 65 | private ItemTouchHelper itemTouchHelper; 66 | @Override 67 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 68 | super.onViewCreated(view, savedInstanceState); 69 | 70 | RecyclerAdapter adapter = new RecyclerAdapter(R.layout.item_grid,results); 71 | recyclerView = (RecyclerView)view; 72 | recyclerView.setHasFixedSize(true); 73 | recyclerView.setAdapter(adapter); 74 | recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 4)); 75 | recyclerView.addItemDecoration(new DividerGridItemDecoration(getActivity())); 76 | 77 | itemTouchHelper = new ItemTouchHelper(new MyItemTouchCallback(adapter).setOnDragListener(this)); 78 | itemTouchHelper.attachToRecyclerView(recyclerView); 79 | 80 | recyclerView.addOnItemTouchListener(new OnRecyclerItemClickListener(recyclerView) { 81 | @Override 82 | public void onLongClick(RecyclerView.ViewHolder vh) { 83 | if (vh.getLayoutPosition()!=results.size()-1) { 84 | itemTouchHelper.startDrag(vh); 85 | VibratorUtil.Vibrate(getActivity(), 70); //震动70ms 86 | } 87 | } 88 | @Override 89 | public void onItemClick(RecyclerView.ViewHolder vh) { 90 | Item item = results.get(vh.getLayoutPosition()); 91 | Toast.makeText(getActivity(),item.getId()+" "+item.getName(),Toast.LENGTH_SHORT).show(); 92 | } 93 | }); 94 | } 95 | 96 | @Override 97 | public void onFinishDrag() { 98 | //存入缓存 99 | ACache.get(getActivity()).put("items",(ArrayList)results); 100 | } 101 | } -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/java/com/liaoinstan/dragrecyclerview/fragment/MyListFragment.java: -------------------------------------------------------------------------------- 1 | package com.liaoinstan.dragrecyclerview.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.Fragment; 6 | import android.support.v7.widget.LinearLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.support.v7.widget.helper.ItemTouchHelper; 9 | import android.view.LayoutInflater; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | 13 | import com.liaoinstan.dragrecyclerview.entity.Item; 14 | import com.liaoinstan.dragrecyclerview.R; 15 | import com.liaoinstan.dragrecyclerview.adapter.RecyclerAdapter; 16 | import com.liaoinstan.dragrecyclerview.helper.MyItemTouchCallback; 17 | import com.liaoinstan.dragrecyclerview.helper.OnRecyclerItemClickListener; 18 | import com.liaoinstan.dragrecyclerview.utils.VibratorUtil; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | 23 | /** 24 | * Created by Administrator on 2016/4/12. 25 | */ 26 | public class MyListFragment extends Fragment{ 27 | 28 | private List results = new ArrayList(); 29 | 30 | @Override 31 | public void onCreate(@Nullable Bundle savedInstanceState) { 32 | super.onCreate(savedInstanceState); 33 | for (int i=0;i<3;i++){ 34 | results.add(new Item(i*8+0,"收款", R.drawable.takeout_ic_category_brand)); 35 | results.add(new Item(i*8+1,"转账", R.drawable.takeout_ic_category_flower)); 36 | results.add(new Item(i*8+2,"余额宝", R.drawable.takeout_ic_category_fruit)); 37 | results.add(new Item(i*8+3,"手机充值", R.drawable.takeout_ic_category_medicine)); 38 | results.add(new Item(i*8+4,"医疗", R.drawable.takeout_ic_category_motorcycle)); 39 | results.add(new Item(i*8+5,"彩票", R.drawable.takeout_ic_category_public)); 40 | results.add(new Item(i*8+6,"电影", R.drawable.takeout_ic_category_store)); 41 | results.add(new Item(i*8+7,"游戏", R.drawable.takeout_ic_category_sweet)); 42 | } 43 | } 44 | 45 | @Nullable 46 | @Override 47 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 48 | return new RecyclerView(container.getContext()); 49 | } 50 | 51 | @Override 52 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 53 | super.onViewCreated(view, savedInstanceState); 54 | 55 | RecyclerAdapter adapter = new RecyclerAdapter(R.layout.item_list,results); 56 | 57 | RecyclerView recyclerView = (RecyclerView)view; 58 | recyclerView.setHasFixedSize(true); 59 | recyclerView.setAdapter(adapter); 60 | recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); 61 | 62 | final ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new MyItemTouchCallback(adapter)); 63 | itemTouchHelper.attachToRecyclerView(recyclerView); 64 | 65 | recyclerView.addOnItemTouchListener(new OnRecyclerItemClickListener(recyclerView) { 66 | @Override 67 | public void onLongClick(RecyclerView.ViewHolder vh) { 68 | if (vh.getLayoutPosition()!=results.size()-1) { 69 | itemTouchHelper.startDrag(vh); 70 | VibratorUtil.Vibrate(getActivity(), 70); //震动70ms 71 | } 72 | } 73 | }); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/java/com/liaoinstan/dragrecyclerview/helper/MyItemTouchCallback.java: -------------------------------------------------------------------------------- 1 | package com.liaoinstan.dragrecyclerview.helper; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Color; 5 | import android.graphics.drawable.Drawable; 6 | import android.support.v7.widget.GridLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.support.v7.widget.helper.ItemTouchHelper; 9 | 10 | /** 11 | * Created by Administrator on 2016/4/12. 12 | */ 13 | public class MyItemTouchCallback extends ItemTouchHelper.Callback { 14 | 15 | private ItemTouchAdapter itemTouchAdapter; 16 | public MyItemTouchCallback(ItemTouchAdapter itemTouchAdapter){ 17 | this.itemTouchAdapter = itemTouchAdapter; 18 | } 19 | 20 | @Override 21 | public boolean isLongPressDragEnabled() { 22 | return false; 23 | } 24 | 25 | @Override 26 | public boolean isItemViewSwipeEnabled() { 27 | return true; 28 | } 29 | 30 | 31 | @Override 32 | public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { 33 | if (recyclerView.getLayoutManager() instanceof GridLayoutManager) { 34 | final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; 35 | final int swipeFlags = 0; 36 | return makeMovementFlags(dragFlags, swipeFlags); 37 | } else { 38 | final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; 39 | //final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; 40 | final int swipeFlags = 0; 41 | return makeMovementFlags(dragFlags, swipeFlags); 42 | } 43 | } 44 | 45 | @Override 46 | public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { 47 | int fromPosition = viewHolder.getAdapterPosition();//得到拖动ViewHolder的position 48 | int toPosition = target.getAdapterPosition();//得到目标ViewHolder的position 49 | itemTouchAdapter.onMove(fromPosition,toPosition); 50 | return true; 51 | } 52 | 53 | @Override 54 | public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { 55 | int position = viewHolder.getAdapterPosition(); 56 | itemTouchAdapter.onSwiped(position); 57 | } 58 | 59 | @Override 60 | public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { 61 | if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { 62 | //滑动时改变Item的透明度 63 | final float alpha = 1 - Math.abs(dX) / (float) viewHolder.itemView.getWidth(); 64 | viewHolder.itemView.setAlpha(alpha); 65 | viewHolder.itemView.setTranslationX(dX); 66 | } else { 67 | super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); 68 | } 69 | } 70 | 71 | @Override 72 | public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { 73 | if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) { 74 | if (background == null && bkcolor == -1) { 75 | Drawable drawable = viewHolder.itemView.getBackground(); 76 | if (drawable == null) { 77 | bkcolor = 0; 78 | } else { 79 | background = drawable; 80 | } 81 | } 82 | viewHolder.itemView.setBackgroundColor(Color.LTGRAY); 83 | } 84 | super.onSelectedChanged(viewHolder, actionState); 85 | } 86 | 87 | @Override 88 | public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { 89 | super.clearView(recyclerView, viewHolder); 90 | 91 | viewHolder.itemView.setAlpha(1.0f); 92 | if (background != null) viewHolder.itemView.setBackgroundDrawable(background); 93 | if (bkcolor != -1) viewHolder.itemView.setBackgroundColor(bkcolor); 94 | //viewHolder.itemView.setBackgroundColor(0); 95 | 96 | if (onDragListener!=null){ 97 | onDragListener.onFinishDrag(); 98 | } 99 | } 100 | 101 | private Drawable background = null; 102 | private int bkcolor = -1; 103 | 104 | private OnDragListener onDragListener; 105 | public MyItemTouchCallback setOnDragListener(OnDragListener onDragListener) { 106 | this.onDragListener = onDragListener; 107 | return this; 108 | } 109 | public interface OnDragListener{ 110 | void onFinishDrag(); 111 | } 112 | 113 | public interface ItemTouchAdapter { 114 | void onMove(int fromPosition,int toPosition); 115 | void onSwiped(int position); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/java/com/liaoinstan/dragrecyclerview/helper/OnRecyclerItemClickListener.java: -------------------------------------------------------------------------------- 1 | package com.liaoinstan.dragrecyclerview.helper; 2 | 3 | import android.support.v4.view.GestureDetectorCompat; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.GestureDetector; 6 | import android.view.MotionEvent; 7 | import android.view.View; 8 | 9 | /** 10 | * Created by Administrator on 2016/4/14. 11 | */ 12 | public class OnRecyclerItemClickListener implements RecyclerView.OnItemTouchListener{ 13 | private GestureDetectorCompat mGestureDetector; 14 | private RecyclerView recyclerView; 15 | 16 | public OnRecyclerItemClickListener(RecyclerView recyclerView){ 17 | this.recyclerView = recyclerView; 18 | mGestureDetector = new GestureDetectorCompat(recyclerView.getContext(),new ItemTouchHelperGestureListener()); 19 | } 20 | 21 | @Override 22 | public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { 23 | mGestureDetector.onTouchEvent(e); 24 | return false; 25 | } 26 | 27 | @Override 28 | public void onTouchEvent(RecyclerView rv, MotionEvent e) { 29 | mGestureDetector.onTouchEvent(e); 30 | } 31 | 32 | @Override 33 | public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { 34 | 35 | } 36 | 37 | private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener { 38 | 39 | @Override 40 | public boolean onSingleTapUp(MotionEvent e) { 41 | View child = recyclerView.findChildViewUnder(e.getX(), e.getY()); 42 | if (child!=null) { 43 | RecyclerView.ViewHolder vh = recyclerView.getChildViewHolder(child); 44 | onItemClick(vh); 45 | } 46 | return true; 47 | } 48 | 49 | @Override 50 | public void onLongPress(MotionEvent e) { 51 | View child = recyclerView.findChildViewUnder(e.getX(), e.getY()); 52 | if (child!=null) { 53 | RecyclerView.ViewHolder vh = recyclerView.getChildViewHolder(child); 54 | onLongClick(vh); 55 | } 56 | } 57 | } 58 | 59 | public void onLongClick(RecyclerView.ViewHolder vh){} 60 | public void onItemClick(RecyclerView.ViewHolder vh){} 61 | } 62 | -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/java/com/liaoinstan/dragrecyclerview/utils/ACache.java: -------------------------------------------------------------------------------- 1 | package com.liaoinstan.dragrecyclerview.utils; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.BitmapFactory; 6 | import android.graphics.Canvas; 7 | import android.graphics.PixelFormat; 8 | import android.graphics.drawable.BitmapDrawable; 9 | import android.graphics.drawable.Drawable; 10 | 11 | import org.json.JSONArray; 12 | import org.json.JSONObject; 13 | 14 | import java.io.BufferedReader; 15 | import java.io.BufferedWriter; 16 | import java.io.ByteArrayInputStream; 17 | import java.io.ByteArrayOutputStream; 18 | import java.io.File; 19 | import java.io.FileInputStream; 20 | import java.io.FileNotFoundException; 21 | import java.io.FileOutputStream; 22 | import java.io.FileReader; 23 | import java.io.FileWriter; 24 | import java.io.IOException; 25 | import java.io.InputStream; 26 | import java.io.ObjectInputStream; 27 | import java.io.ObjectOutputStream; 28 | import java.io.OutputStream; 29 | import java.io.RandomAccessFile; 30 | import java.io.Serializable; 31 | import java.util.Collections; 32 | import java.util.HashMap; 33 | import java.util.Map; 34 | import java.util.Map.Entry; 35 | import java.util.Set; 36 | import java.util.concurrent.atomic.AtomicInteger; 37 | import java.util.concurrent.atomic.AtomicLong; 38 | 39 | /** 40 | * 这是一个缓存工具类,提供数据的本地化方法 41 | */ 42 | public class ACache { 43 | public static final int TIME_HOUR = 60 * 60; 44 | public static final int TIME_DAY = TIME_HOUR * 24; 45 | private static final int MAX_SIZE = 1000 * 1000 * 50; // 50 mb 46 | private static final int MAX_COUNT = Integer.MAX_VALUE; // 不限制存放数据的数量 47 | private static Map mInstanceMap = new HashMap(); 48 | private ACacheManager mCache; 49 | 50 | public static ACache get(Context ctx) { 51 | return get(ctx, "ACache"); 52 | } 53 | 54 | public static ACache get(Context ctx, String cacheName) { 55 | File f = new File(ctx.getCacheDir(), cacheName); 56 | return get(f, MAX_SIZE, MAX_COUNT); 57 | } 58 | 59 | public static ACache get(File cacheDir) { 60 | return get(cacheDir, MAX_SIZE, MAX_COUNT); 61 | } 62 | 63 | public static ACache get(Context ctx, long max_zise, int max_count) { 64 | File f = new File(ctx.getCacheDir(), "ACache"); 65 | return get(f, max_zise, max_count); 66 | } 67 | 68 | public static ACache get(File cacheDir, long max_zise, int max_count) { 69 | ACache manager = mInstanceMap.get(cacheDir.getAbsoluteFile() + myPid()); 70 | if (manager == null) { 71 | manager = new ACache(cacheDir, max_zise, max_count); 72 | mInstanceMap.put(cacheDir.getAbsolutePath() + myPid(), manager); 73 | } 74 | return manager; 75 | } 76 | 77 | private static String myPid() { 78 | return "_" + android.os.Process.myPid(); 79 | } 80 | 81 | private ACache(File cacheDir, long max_size, int max_count) { 82 | if (!cacheDir.exists() && !cacheDir.mkdirs()) { 83 | throw new RuntimeException("can't make dirs in " + cacheDir.getAbsolutePath()); 84 | } 85 | mCache = new ACacheManager(cacheDir, max_size, max_count); 86 | } 87 | 88 | /** 89 | * Provides a means to save a cached file before the data are available. 90 | * Since writing about the file is complete, and its close method is called, 91 | * its contents will be registered in the cache. Example of use: 92 | * 93 | * ACache cache = new ACache(this) try { OutputStream stream = 94 | * cache.put("myFileName") stream.write("some bytes".getBytes()); // now 95 | * update cache! stream.close(); } catch(FileNotFoundException e){ 96 | * e.printStackTrace() } 97 | */ 98 | class xFileOutputStream extends FileOutputStream { 99 | File file; 100 | 101 | public xFileOutputStream(File file) throws FileNotFoundException { 102 | super(file); 103 | this.file = file; 104 | } 105 | 106 | public void close() throws IOException { 107 | super.close(); 108 | mCache.put(file); 109 | } 110 | } 111 | 112 | // ======================================= 113 | // ============ String数据 读写 ============== 114 | // ======================================= 115 | /** 116 | * 保存 String数据 到 缓存中 117 | * 118 | * @param key 119 | * 保存的key 120 | * @param value 121 | * 保存的String数据 122 | */ 123 | public void put(String key, String value) { 124 | File file = mCache.newFile(key); 125 | BufferedWriter out = null; 126 | try { 127 | out = new BufferedWriter(new FileWriter(file), 1024); 128 | out.write(value); 129 | } catch (IOException e) { 130 | e.printStackTrace(); 131 | } finally { 132 | if (out != null) { 133 | try { 134 | out.flush(); 135 | out.close(); 136 | } catch (IOException e) { 137 | e.printStackTrace(); 138 | } 139 | } 140 | mCache.put(file); 141 | } 142 | } 143 | 144 | /** 145 | * 保存 String数据 到 缓存中 146 | * 147 | * @param key 148 | * 保存的key 149 | * @param value 150 | * 保存的String数据 151 | * @param saveTime 152 | * 保存的时间,单位:秒 153 | */ 154 | public void put(String key, String value, int saveTime) { 155 | put(key, Utils.newStringWithDateInfo(saveTime, value)); 156 | } 157 | 158 | /** 159 | * 读取 String数据 160 | * 161 | * @param key 162 | * @return String 数据 163 | */ 164 | public String getAsString(String key) { 165 | File file = mCache.get(key); 166 | if (!file.exists()) 167 | return null; 168 | boolean removeFile = false; 169 | BufferedReader in = null; 170 | try { 171 | in = new BufferedReader(new FileReader(file)); 172 | String readString = ""; 173 | String currentLine; 174 | while ((currentLine = in.readLine()) != null) { 175 | readString += currentLine; 176 | } 177 | if (!Utils.isDue(readString)) { 178 | return Utils.clearDateInfo(readString); 179 | } else { 180 | removeFile = true; 181 | return null; 182 | } 183 | } catch (IOException e) { 184 | e.printStackTrace(); 185 | return null; 186 | } finally { 187 | if (in != null) { 188 | try { 189 | in.close(); 190 | } catch (IOException e) { 191 | e.printStackTrace(); 192 | } 193 | } 194 | if (removeFile) 195 | remove(key); 196 | } 197 | } 198 | 199 | // ======================================= 200 | // ============= JSONObject 数据 读写 ============== 201 | // ======================================= 202 | /** 203 | * 保存 JSONObject数据 到 缓存中 204 | * 205 | * @param key 206 | * 保存的key 207 | * @param value 208 | * 保存的JSON数据 209 | */ 210 | public void put(String key, JSONObject value) { 211 | put(key, value.toString()); 212 | } 213 | 214 | /** 215 | * 保存 JSONObject数据 到 缓存中 216 | * 217 | * @param key 218 | * 保存的key 219 | * @param value 220 | * 保存的JSONObject数据 221 | * @param saveTime 222 | * 保存的时间,单位:秒 223 | */ 224 | public void put(String key, JSONObject value, int saveTime) { 225 | put(key, value.toString(), saveTime); 226 | } 227 | 228 | /** 229 | * 读取JSONObject数据 230 | * 231 | * @param key 232 | * @return JSONObject数据 233 | */ 234 | public JSONObject getAsJSONObject(String key) { 235 | String JSONString = getAsString(key); 236 | try { 237 | JSONObject obj = new JSONObject(JSONString); 238 | return obj; 239 | } catch (Exception e) { 240 | e.printStackTrace(); 241 | return null; 242 | } 243 | } 244 | 245 | // ======================================= 246 | // ============ JSONArray 数据 读写 ============= 247 | // ======================================= 248 | /** 249 | * 保存 JSONArray数据 到 缓存中 250 | * 251 | * @param key 252 | * 保存的key 253 | * @param value 254 | * 保存的JSONArray数据 255 | */ 256 | public void put(String key, JSONArray value) { 257 | put(key, value.toString()); 258 | } 259 | 260 | /** 261 | * 保存 JSONArray数据 到 缓存中 262 | * 263 | * @param key 264 | * 保存的key 265 | * @param value 266 | * 保存的JSONArray数据 267 | * @param saveTime 268 | * 保存的时间,单位:秒 269 | */ 270 | public void put(String key, JSONArray value, int saveTime) { 271 | put(key, value.toString(), saveTime); 272 | } 273 | 274 | /** 275 | * 读取JSONArray数据 276 | * 277 | * @param key 278 | * @return JSONArray数据 279 | */ 280 | public JSONArray getAsJSONArray(String key) { 281 | String JSONString = getAsString(key); 282 | try { 283 | JSONArray obj = new JSONArray(JSONString); 284 | return obj; 285 | } catch (Exception e) { 286 | e.printStackTrace(); 287 | return null; 288 | } 289 | } 290 | 291 | // ======================================= 292 | // ============== byte 数据 读写 ============= 293 | // ======================================= 294 | /** 295 | * 保存 byte数据 到 缓存中 296 | * 297 | * @param key 298 | * 保存的key 299 | * @param value 300 | * 保存的数据 301 | */ 302 | public void put(String key, byte[] value) { 303 | File file = mCache.newFile(key); 304 | FileOutputStream out = null; 305 | try { 306 | out = new FileOutputStream(file); 307 | out.write(value); 308 | } catch (Exception e) { 309 | e.printStackTrace(); 310 | } finally { 311 | if (out != null) { 312 | try { 313 | out.flush(); 314 | out.close(); 315 | } catch (IOException e) { 316 | e.printStackTrace(); 317 | } 318 | } 319 | mCache.put(file); 320 | } 321 | } 322 | 323 | /** 324 | * Cache for a stream 325 | * 326 | * @param key 327 | * the file name. 328 | * @return OutputStream stream for writing data. 329 | * @throws FileNotFoundException 330 | * if the file can not be created. 331 | */ 332 | public OutputStream put(String key) throws FileNotFoundException { 333 | return new xFileOutputStream(mCache.newFile(key)); 334 | } 335 | 336 | /** 337 | * 338 | * @param key 339 | * the file name. 340 | * @return (InputStream or null) stream previously saved in cache. 341 | * @throws FileNotFoundException 342 | * if the file can not be opened 343 | */ 344 | public InputStream get(String key) throws FileNotFoundException { 345 | File file = mCache.get(key); 346 | if (!file.exists()) 347 | return null; 348 | return new FileInputStream(file); 349 | } 350 | 351 | /** 352 | * 保存 byte数据 到 缓存中 353 | * 354 | * @param key 355 | * 保存的key 356 | * @param value 357 | * 保存的数据 358 | * @param saveTime 359 | * 保存的时间,单位:秒 360 | */ 361 | public void put(String key, byte[] value, int saveTime) { 362 | put(key, Utils.newByteArrayWithDateInfo(saveTime, value)); 363 | } 364 | 365 | /** 366 | * 获取 byte 数据 367 | * 368 | * @param key 369 | * @return byte 数据 370 | */ 371 | public byte[] getAsBinary(String key) { 372 | RandomAccessFile RAFile = null; 373 | boolean removeFile = false; 374 | try { 375 | File file = mCache.get(key); 376 | if (!file.exists()) 377 | return null; 378 | RAFile = new RandomAccessFile(file, "r"); 379 | byte[] byteArray = new byte[(int) RAFile.length()]; 380 | RAFile.read(byteArray); 381 | if (!Utils.isDue(byteArray)) { 382 | return Utils.clearDateInfo(byteArray); 383 | } else { 384 | removeFile = true; 385 | return null; 386 | } 387 | } catch (Exception e) { 388 | e.printStackTrace(); 389 | return null; 390 | } finally { 391 | if (RAFile != null) { 392 | try { 393 | RAFile.close(); 394 | } catch (IOException e) { 395 | e.printStackTrace(); 396 | } 397 | } 398 | if (removeFile) 399 | remove(key); 400 | } 401 | } 402 | 403 | // ======================================= 404 | // ============= 序列化 数据 读写 =============== 405 | // ======================================= 406 | /** 407 | * 保存 Serializable数据 到 缓存中 408 | * 409 | * @param key 410 | * 保存的key 411 | * @param value 412 | * 保存的value 413 | */ 414 | public void put(String key, Serializable value) { 415 | put(key, value, -1); 416 | } 417 | 418 | /** 419 | * 保存 Serializable数据到 缓存中 420 | * 421 | * @param key 422 | * 保存的key 423 | * @param value 424 | * 保存的value 425 | * @param saveTime 426 | * 保存的时间,单位:秒 427 | */ 428 | public void put(String key, Serializable value, int saveTime) { 429 | ByteArrayOutputStream baos = null; 430 | ObjectOutputStream oos = null; 431 | try { 432 | baos = new ByteArrayOutputStream(); 433 | oos = new ObjectOutputStream(baos); 434 | oos.writeObject(value); 435 | byte[] data = baos.toByteArray(); 436 | if (saveTime != -1) { 437 | put(key, data, saveTime); 438 | } else { 439 | put(key, data); 440 | } 441 | } catch (Exception e) { 442 | e.printStackTrace(); 443 | } finally { 444 | try { 445 | oos.close(); 446 | } catch (IOException e) { 447 | } 448 | } 449 | } 450 | 451 | /** 452 | * 读取 Serializable数据 453 | * 454 | * @param key 455 | * @return Serializable 数据 456 | */ 457 | public Object getAsObject(String key) { 458 | byte[] data = getAsBinary(key); 459 | if (data != null) { 460 | ByteArrayInputStream bais = null; 461 | ObjectInputStream ois = null; 462 | try { 463 | bais = new ByteArrayInputStream(data); 464 | ois = new ObjectInputStream(bais); 465 | Object reObject = ois.readObject(); 466 | return reObject; 467 | } catch (Exception e) { 468 | e.printStackTrace(); 469 | return null; 470 | } finally { 471 | try { 472 | if (bais != null) 473 | bais.close(); 474 | } catch (IOException e) { 475 | e.printStackTrace(); 476 | } 477 | try { 478 | if (ois != null) 479 | ois.close(); 480 | } catch (IOException e) { 481 | e.printStackTrace(); 482 | } 483 | } 484 | } 485 | return null; 486 | 487 | } 488 | 489 | // ======================================= 490 | // ============== bitmap 数据 读写 ============= 491 | // ======================================= 492 | /** 493 | * 保存 bitmap 到 缓存中 494 | * 495 | * @param key 496 | * 保存的key 497 | * @param value 498 | * 保存的bitmap数据 499 | */ 500 | public void put(String key, Bitmap value) { 501 | put(key, Utils.Bitmap2Bytes(value)); 502 | } 503 | 504 | /** 505 | * 保存 bitmap 到 缓存中 506 | * 507 | * @param key 508 | * 保存的key 509 | * @param value 510 | * 保存的 bitmap 数据 511 | * @param saveTime 512 | * 保存的时间,单位:秒 513 | */ 514 | public void put(String key, Bitmap value, int saveTime) { 515 | put(key, Utils.Bitmap2Bytes(value), saveTime); 516 | } 517 | 518 | /** 519 | * 读取 bitmap 数据 520 | * 521 | * @param key 522 | * @return bitmap 数据 523 | */ 524 | public Bitmap getAsBitmap(String key) { 525 | if (getAsBinary(key) == null) { 526 | return null; 527 | } 528 | return Utils.Bytes2Bimap(getAsBinary(key)); 529 | } 530 | 531 | // ======================================= 532 | // ============= drawable 数据 读写 ============= 533 | // ======================================= 534 | /** 535 | * 保存 drawable 到 缓存中 536 | * 537 | * @param key 538 | * 保存的key 539 | * @param value 540 | * 保存的drawable数据 541 | */ 542 | public void put(String key, Drawable value) { 543 | put(key, Utils.drawable2Bitmap(value)); 544 | } 545 | 546 | /** 547 | * 保存 drawable 到 缓存中 548 | * 549 | * @param key 550 | * 保存的key 551 | * @param value 552 | * 保存的 drawable 数据 553 | * @param saveTime 554 | * 保存的时间,单位:秒 555 | */ 556 | public void put(String key, Drawable value, int saveTime) { 557 | put(key, Utils.drawable2Bitmap(value), saveTime); 558 | } 559 | 560 | /** 561 | * 读取 Drawable 数据 562 | * 563 | * @param key 564 | * @return Drawable 数据 565 | */ 566 | public Drawable getAsDrawable(String key) { 567 | if (getAsBinary(key) == null) { 568 | return null; 569 | } 570 | return Utils.bitmap2Drawable(Utils.Bytes2Bimap(getAsBinary(key))); 571 | } 572 | 573 | /** 574 | * 获取缓存文件 575 | * 576 | * @param key 577 | * @return value 缓存的文件 578 | */ 579 | public File file(String key) { 580 | File f = mCache.newFile(key); 581 | if (f.exists()) 582 | return f; 583 | return null; 584 | } 585 | 586 | /** 587 | * 移除某个key 588 | * 589 | * @param key 590 | * @return 是否移除成功 591 | */ 592 | public boolean remove(String key) { 593 | return mCache.remove(key); 594 | } 595 | 596 | /** 597 | * 清除所有数据 598 | */ 599 | public void clear() { 600 | mCache.clear(); 601 | } 602 | 603 | /** 604 | * @title 缓存管理器 605 | * @author 杨福海(michael) www.yangfuhai.com 606 | * @version 1.0 607 | */ 608 | public class ACacheManager { 609 | private final AtomicLong cacheSize; 610 | private final AtomicInteger cacheCount; 611 | private final long sizeLimit; 612 | private final int countLimit; 613 | private final Map lastUsageDates = Collections.synchronizedMap(new HashMap()); 614 | protected File cacheDir; 615 | 616 | private ACacheManager(File cacheDir, long sizeLimit, int countLimit) { 617 | this.cacheDir = cacheDir; 618 | this.sizeLimit = sizeLimit; 619 | this.countLimit = countLimit; 620 | cacheSize = new AtomicLong(); 621 | cacheCount = new AtomicInteger(); 622 | calculateCacheSizeAndCacheCount(); 623 | } 624 | 625 | /** 626 | * 计算 cacheSize和cacheCount 627 | */ 628 | private void calculateCacheSizeAndCacheCount() { 629 | new Thread(new Runnable() { 630 | @Override 631 | public void run() { 632 | int size = 0; 633 | int count = 0; 634 | File[] cachedFiles = cacheDir.listFiles(); 635 | if (cachedFiles != null) { 636 | for (File cachedFile : cachedFiles) { 637 | size += calculateSize(cachedFile); 638 | count += 1; 639 | lastUsageDates.put(cachedFile, cachedFile.lastModified()); 640 | } 641 | cacheSize.set(size); 642 | cacheCount.set(count); 643 | } 644 | } 645 | }).start(); 646 | } 647 | 648 | private void put(File file) { 649 | int curCacheCount = cacheCount.get(); 650 | while (curCacheCount + 1 > countLimit) { 651 | long freedSize = removeNext(); 652 | cacheSize.addAndGet(-freedSize); 653 | 654 | curCacheCount = cacheCount.addAndGet(-1); 655 | } 656 | cacheCount.addAndGet(1); 657 | 658 | long valueSize = calculateSize(file); 659 | long curCacheSize = cacheSize.get(); 660 | while (curCacheSize + valueSize > sizeLimit) { 661 | long freedSize = removeNext(); 662 | curCacheSize = cacheSize.addAndGet(-freedSize); 663 | } 664 | cacheSize.addAndGet(valueSize); 665 | 666 | Long currentTime = System.currentTimeMillis(); 667 | file.setLastModified(currentTime); 668 | lastUsageDates.put(file, currentTime); 669 | } 670 | 671 | private File get(String key) { 672 | File file = newFile(key); 673 | Long currentTime = System.currentTimeMillis(); 674 | file.setLastModified(currentTime); 675 | lastUsageDates.put(file, currentTime); 676 | 677 | return file; 678 | } 679 | 680 | private File newFile(String key) { 681 | return new File(cacheDir, key.hashCode() + ""); 682 | } 683 | 684 | private boolean remove(String key) { 685 | File image = get(key); 686 | return image.delete(); 687 | } 688 | 689 | private void clear() { 690 | lastUsageDates.clear(); 691 | cacheSize.set(0); 692 | File[] files = cacheDir.listFiles(); 693 | if (files != null) { 694 | for (File f : files) { 695 | f.delete(); 696 | } 697 | } 698 | } 699 | 700 | /** 701 | * 移除旧的文件 702 | * 703 | * @return 704 | */ 705 | private long removeNext() { 706 | if (lastUsageDates.isEmpty()) { 707 | return 0; 708 | } 709 | 710 | Long oldestUsage = null; 711 | File mostLongUsedFile = null; 712 | Set> entries = lastUsageDates.entrySet(); 713 | synchronized (lastUsageDates) { 714 | for (Entry entry : entries) { 715 | if (mostLongUsedFile == null) { 716 | mostLongUsedFile = entry.getKey(); 717 | oldestUsage = entry.getValue(); 718 | } else { 719 | Long lastValueUsage = entry.getValue(); 720 | if (lastValueUsage < oldestUsage) { 721 | oldestUsage = lastValueUsage; 722 | mostLongUsedFile = entry.getKey(); 723 | } 724 | } 725 | } 726 | } 727 | 728 | long fileSize = calculateSize(mostLongUsedFile); 729 | if (mostLongUsedFile.delete()) { 730 | lastUsageDates.remove(mostLongUsedFile); 731 | } 732 | return fileSize; 733 | } 734 | 735 | private long calculateSize(File file) { 736 | return file.length(); 737 | } 738 | } 739 | 740 | /** 741 | * @title 时间计算工具类 742 | * @author 杨福海(michael) www.yangfuhai.com 743 | * @version 1.0 744 | */ 745 | private static class Utils { 746 | 747 | /** 748 | * 判断缓存的String数据是否到期 749 | * 750 | * @param str 751 | * @return true:到期了 false:还没有到期 752 | */ 753 | private static boolean isDue(String str) { 754 | return isDue(str.getBytes()); 755 | } 756 | 757 | /** 758 | * 判断缓存的byte数据是否到期 759 | * 760 | * @param data 761 | * @return true:到期了 false:还没有到期 762 | */ 763 | private static boolean isDue(byte[] data) { 764 | String[] strs = getDateInfoFromDate(data); 765 | if (strs != null && strs.length == 2) { 766 | String saveTimeStr = strs[0]; 767 | while (saveTimeStr.startsWith("0")) { 768 | saveTimeStr = saveTimeStr.substring(1, saveTimeStr.length()); 769 | } 770 | long saveTime = Long.valueOf(saveTimeStr); 771 | long deleteAfter = Long.valueOf(strs[1]); 772 | if (System.currentTimeMillis() > saveTime + deleteAfter * 1000) { 773 | return true; 774 | } 775 | } 776 | return false; 777 | } 778 | 779 | private static String newStringWithDateInfo(int second, String strInfo) { 780 | return createDateInfo(second) + strInfo; 781 | } 782 | 783 | private static byte[] newByteArrayWithDateInfo(int second, byte[] data2) { 784 | byte[] data1 = createDateInfo(second).getBytes(); 785 | byte[] retdata = new byte[data1.length + data2.length]; 786 | System.arraycopy(data1, 0, retdata, 0, data1.length); 787 | System.arraycopy(data2, 0, retdata, data1.length, data2.length); 788 | return retdata; 789 | } 790 | 791 | private static String clearDateInfo(String strInfo) { 792 | if (strInfo != null && hasDateInfo(strInfo.getBytes())) { 793 | strInfo = strInfo.substring(strInfo.indexOf(mSeparator) + 1, strInfo.length()); 794 | } 795 | return strInfo; 796 | } 797 | 798 | private static byte[] clearDateInfo(byte[] data) { 799 | if (hasDateInfo(data)) { 800 | return copyOfRange(data, indexOf(data, mSeparator) + 1, data.length); 801 | } 802 | return data; 803 | } 804 | 805 | private static boolean hasDateInfo(byte[] data) { 806 | return data != null && data.length > 15 && data[13] == '-' && indexOf(data, mSeparator) > 14; 807 | } 808 | 809 | private static String[] getDateInfoFromDate(byte[] data) { 810 | if (hasDateInfo(data)) { 811 | String saveDate = new String(copyOfRange(data, 0, 13)); 812 | String deleteAfter = new String(copyOfRange(data, 14, indexOf(data, mSeparator))); 813 | return new String[] { saveDate, deleteAfter }; 814 | } 815 | return null; 816 | } 817 | 818 | private static int indexOf(byte[] data, char c) { 819 | for (int i = 0; i < data.length; i++) { 820 | if (data[i] == c) { 821 | return i; 822 | } 823 | } 824 | return -1; 825 | } 826 | 827 | private static byte[] copyOfRange(byte[] original, int from, int to) { 828 | int newLength = to - from; 829 | if (newLength < 0) 830 | throw new IllegalArgumentException(from + " > " + to); 831 | byte[] copy = new byte[newLength]; 832 | System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength)); 833 | return copy; 834 | } 835 | 836 | private static final char mSeparator = ' '; 837 | 838 | private static String createDateInfo(int second) { 839 | String currentTime = System.currentTimeMillis() + ""; 840 | while (currentTime.length() < 13) { 841 | currentTime = "0" + currentTime; 842 | } 843 | return currentTime + "-" + second + mSeparator; 844 | } 845 | 846 | /* 847 | * Bitmap → byte[] 848 | */ 849 | private static byte[] Bitmap2Bytes(Bitmap bm) { 850 | if (bm == null) { 851 | return null; 852 | } 853 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 854 | bm.compress(Bitmap.CompressFormat.PNG, 100, baos); 855 | return baos.toByteArray(); 856 | } 857 | 858 | /* 859 | * byte[] → Bitmap 860 | */ 861 | private static Bitmap Bytes2Bimap(byte[] b) { 862 | if (b.length == 0) { 863 | return null; 864 | } 865 | return BitmapFactory.decodeByteArray(b, 0, b.length); 866 | } 867 | 868 | /* 869 | * Drawable → Bitmap 870 | */ 871 | private static Bitmap drawable2Bitmap(Drawable drawable) { 872 | if (drawable == null) { 873 | return null; 874 | } 875 | // 取 drawable 的长宽 876 | int w = drawable.getIntrinsicWidth(); 877 | int h = drawable.getIntrinsicHeight(); 878 | // 取 drawable 的颜色格式 879 | Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565; 880 | // 建立对应 bitmap 881 | Bitmap bitmap = Bitmap.createBitmap(w, h, config); 882 | // 建立对应 bitmap 的画布 883 | Canvas canvas = new Canvas(bitmap); 884 | drawable.setBounds(0, 0, w, h); 885 | // 把 drawable 内容画到画布中 886 | drawable.draw(canvas); 887 | return bitmap; 888 | } 889 | 890 | /* 891 | * Bitmap → Drawable 892 | */ 893 | @SuppressWarnings("deprecation") 894 | private static Drawable bitmap2Drawable(Bitmap bm) { 895 | if (bm == null) { 896 | return null; 897 | } 898 | BitmapDrawable bd=new BitmapDrawable(bm); 899 | bd.setTargetDensity(bm.getDensity()); 900 | return new BitmapDrawable(bm); 901 | } 902 | } 903 | 904 | } 905 | -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/java/com/liaoinstan/dragrecyclerview/utils/VibratorUtil.java: -------------------------------------------------------------------------------- 1 | package com.liaoinstan.dragrecyclerview.utils; 2 | 3 | import android.app.Activity; 4 | import android.app.Service; 5 | import android.os.Vibrator; 6 | 7 | /** 8 | * 手机震动工具类 9 | * @author Administrator 10 | * 使用必须添加权限: 11 | */ 12 | public class VibratorUtil { 13 | 14 | /** 15 | * final Activity activity :调用该方法的Activity实例 16 | * long milliseconds :震动的时长,单位是毫秒 17 | * long[] pattern :自定义震动模式 。数组中数字的含义依次是[静止时长,震动时长,静止时长,震动时长。。。]时长的单位是毫秒 18 | * boolean isRepeat : 是否反复震动,如果是true,反复震动,如果是false,只震动一次 19 | */ 20 | public static void Vibrate(final Activity activity, long milliseconds) { 21 | Vibrator vib = (Vibrator) activity.getSystemService(Service.VIBRATOR_SERVICE); 22 | vib.vibrate(milliseconds); 23 | } 24 | public static void Vibrate(final Activity activity, long[] pattern, boolean isRepeat) { 25 | Vibrator vib = (Vibrator) activity.getSystemService(Service.VIBRATOR_SERVICE); 26 | vib.vibrate(pattern, isRepeat ? 1 : -1); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/res/drawable-xhdpi/item_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wschkd123/DragRecyclerView/a0c9f4d5637f7cd461a6151cdc6487311ba8426f/5DragRecyclerView/src/main/res/drawable-xhdpi/item_img.png -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_category_brand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wschkd123/DragRecyclerView/a0c9f4d5637f7cd461a6151cdc6487311ba8426f/5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_category_brand.png -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_category_flower.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wschkd123/DragRecyclerView/a0c9f4d5637f7cd461a6151cdc6487311ba8426f/5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_category_flower.png -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_category_fruit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wschkd123/DragRecyclerView/a0c9f4d5637f7cd461a6151cdc6487311ba8426f/5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_category_fruit.png -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_category_medicine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wschkd123/DragRecyclerView/a0c9f4d5637f7cd461a6151cdc6487311ba8426f/5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_category_medicine.png -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_category_motorcycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wschkd123/DragRecyclerView/a0c9f4d5637f7cd461a6151cdc6487311ba8426f/5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_category_motorcycle.png -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_category_public.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wschkd123/DragRecyclerView/a0c9f4d5637f7cd461a6151cdc6487311ba8426f/5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_category_public.png -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_category_store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wschkd123/DragRecyclerView/a0c9f4d5637f7cd461a6151cdc6487311ba8426f/5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_category_store.png -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_category_sweet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wschkd123/DragRecyclerView/a0c9f4d5637f7cd461a6151cdc6487311ba8426f/5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_category_sweet.png -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wschkd123/DragRecyclerView/a0c9f4d5637f7cd461a6151cdc6487311ba8426f/5DragRecyclerView/src/main/res/drawable-xhdpi/takeout_ic_more.png -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 21 | 22 | 23 | 24 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /5DragRecyclerView/src/main/res/layout/fragment_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 |