initial repo for android!

This commit is contained in:
OnlyPapy98
2025-09-25 12:40:44 +02:00
commit 1f34b9cfed
169 changed files with 12099 additions and 0 deletions

13
library/.gitignore vendored Normal file
View File

@@ -0,0 +1,13 @@
.gradle/
.DS_Store
local.properties
# build files
build/
bin/
gen/
output/
# android studio
*.iml
.idea

53
library/build.gradle Normal file
View File

@@ -0,0 +1,53 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
minSdkVersion 11
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
}
// 打包源码jar
task sourcesJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier = 'sources'
}
task javadoc(type: Javadoc) {
failOnError false
source = android.sourceSets.main.java.sourceFiles
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
classpath += configurations.compile
}
// 打包文档jar
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives sourcesJar
archives javadocJar
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
provided 'com.android.support:recyclerview-v7:25.2.0'
}

17
library/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/huasheng/Desktop/sdk/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 *;
#}

View File

@@ -0,0 +1,3 @@
<manifest package="com.chad.library"
xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

View File

@@ -0,0 +1,256 @@
package com.chad.library.adapter.base;
import android.graphics.Canvas;
import android.support.annotation.NonNull;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.MotionEvent;
import android.view.View;
import com.chad.library.R;
import com.chad.library.adapter.base.callback.ItemDragAndSwipeCallback;
import com.chad.library.adapter.base.listener.OnItemDragListener;
import com.chad.library.adapter.base.listener.OnItemSwipeListener;
import java.util.Collections;
import java.util.List;
/**
* Created by luoxw on 2016/7/13.
*/
public abstract class BaseItemDraggableAdapter<T, K extends BaseViewHolder> extends BaseQuickAdapter<T, K> {
private static final int NO_TOGGLE_VIEW = 0;
protected int mToggleViewId = NO_TOGGLE_VIEW;
protected ItemTouchHelper mItemTouchHelper;
protected boolean itemDragEnabled = false;
protected boolean itemSwipeEnabled = false;
protected OnItemDragListener mOnItemDragListener;
protected OnItemSwipeListener mOnItemSwipeListener;
protected boolean mDragOnLongPress = true;
protected View.OnTouchListener mOnToggleViewTouchListener;
protected View.OnLongClickListener mOnToggleViewLongClickListener;
private static final String ERROR_NOT_SAME_ITEMTOUCHHELPER = "Item drag and item swipe should pass the same ItemTouchHelper";
public BaseItemDraggableAdapter(List<T> data) {
super(data);
}
public BaseItemDraggableAdapter(int layoutResId, List<T> data) {
super(layoutResId, data);
}
/**
* To bind different types of holder and solve different the bind events
*
* @param holder
* @param positions
* @see #getDefItemViewType(int)
*/
@Override
public void onBindViewHolder(K holder, int positions) {
super.onBindViewHolder(holder, positions);
int viewType = holder.getItemViewType();
if (mItemTouchHelper != null && itemDragEnabled && viewType != LOADING_VIEW && viewType != HEADER_VIEW
&& viewType != EMPTY_VIEW && viewType != FOOTER_VIEW) {
if (mToggleViewId != NO_TOGGLE_VIEW) {
View toggleView = ((BaseViewHolder) holder).getView(mToggleViewId);
if (toggleView != null) {
toggleView.setTag(R.id.BaseQuickAdapter_viewholder_support, holder);
if (mDragOnLongPress) {
toggleView.setOnLongClickListener(mOnToggleViewLongClickListener);
} else {
toggleView.setOnTouchListener(mOnToggleViewTouchListener);
}
}
} else {
holder.itemView.setTag(R.id.BaseQuickAdapter_viewholder_support, holder);
holder.itemView.setOnLongClickListener(mOnToggleViewLongClickListener);
}
}
}
/**
* Set the toggle view's id which will trigger drag event.
* If the toggle view id is not set, drag event will be triggered when the item is long pressed.
*
* @param toggleViewId the toggle view's id
*/
public void setToggleViewId(int toggleViewId) {
mToggleViewId = toggleViewId;
}
/**
* Set the drag event should be trigger on long press.
* Work when the toggleViewId has been set.
*
* @param longPress by default is true.
*/
public void setToggleDragOnLongPress(boolean longPress) {
mDragOnLongPress = longPress;
if (mDragOnLongPress) {
mOnToggleViewTouchListener = null;
mOnToggleViewLongClickListener = new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (mItemTouchHelper != null && itemDragEnabled) {
mItemTouchHelper.startDrag((RecyclerView.ViewHolder) v.getTag(R.id.BaseQuickAdapter_viewholder_support));
}
return true;
}
};
} else {
mOnToggleViewTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN
&& !mDragOnLongPress) {
if (mItemTouchHelper != null && itemDragEnabled) {
mItemTouchHelper.startDrag((RecyclerView.ViewHolder) v.getTag(R.id.BaseQuickAdapter_viewholder_support));
}
return true;
} else {
return false;
}
}
};
mOnToggleViewLongClickListener = null;
}
}
/**
* Enable drag items.
* Use itemView as the toggleView when long pressed.
*
* @param itemTouchHelper {@link ItemTouchHelper}
*/
public void enableDragItem(@NonNull ItemTouchHelper itemTouchHelper) {
enableDragItem(itemTouchHelper, NO_TOGGLE_VIEW, true);
}
/**
* Enable drag items. Use the specified view as toggle.
*
* @param itemTouchHelper {@link ItemTouchHelper}
* @param toggleViewId The toggle view's id.
* @param dragOnLongPress If true the drag event will be trigger on long press, otherwise on touch down.
*/
public void enableDragItem(@NonNull ItemTouchHelper itemTouchHelper, int toggleViewId, boolean dragOnLongPress) {
itemDragEnabled = true;
mItemTouchHelper = itemTouchHelper;
setToggleViewId(toggleViewId);
setToggleDragOnLongPress(dragOnLongPress);
}
/**
* Disable drag items.
*/
public void disableDragItem() {
itemDragEnabled = false;
mItemTouchHelper = null;
}
public boolean isItemDraggable() {
return itemDragEnabled;
}
/**
* <p>Enable swipe items.</p>
* You should attach {@link ItemTouchHelper} which construct with {@link ItemDragAndSwipeCallback} to the Recycler when you enable this.
*/
public void enableSwipeItem() {
itemSwipeEnabled = true;
}
public void disableSwipeItem() {
itemSwipeEnabled = false;
}
public boolean isItemSwipeEnable() {
return itemSwipeEnabled;
}
/**
* @param onItemDragListener Register a callback to be invoked when drag event happen.
*/
public void setOnItemDragListener(OnItemDragListener onItemDragListener) {
mOnItemDragListener = onItemDragListener;
}
public int getViewHolderPosition(RecyclerView.ViewHolder viewHolder) {
return viewHolder.getAdapterPosition() - getHeaderLayoutCount();
}
public void onItemDragStart(RecyclerView.ViewHolder viewHolder) {
if (mOnItemDragListener != null && itemDragEnabled) {
mOnItemDragListener.onItemDragStart(viewHolder, getViewHolderPosition(viewHolder));
}
}
public void onItemDragMoving(RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
int from = getViewHolderPosition(source);
int to = getViewHolderPosition(target);
if (from < to) {
for (int i = from; i < to; i++) {
Collections.swap(mData, i, i + 1);
}
} else {
for (int i = from; i > to; i--) {
Collections.swap(mData, i, i - 1);
}
}
notifyItemMoved(source.getAdapterPosition(), target.getAdapterPosition());
if (mOnItemDragListener != null && itemDragEnabled) {
mOnItemDragListener.onItemDragMoving(source, from, target, to);
}
}
public void onItemDragEnd(RecyclerView.ViewHolder viewHolder) {
if (mOnItemDragListener != null && itemDragEnabled) {
mOnItemDragListener.onItemDragEnd(viewHolder, getViewHolderPosition(viewHolder));
}
}
public void setOnItemSwipeListener(OnItemSwipeListener listener) {
mOnItemSwipeListener = listener;
}
public void onItemSwipeStart(RecyclerView.ViewHolder viewHolder) {
if (mOnItemSwipeListener != null && itemSwipeEnabled) {
mOnItemSwipeListener.onItemSwipeStart(viewHolder, getViewHolderPosition(viewHolder));
}
}
public void onItemSwipeClear(RecyclerView.ViewHolder viewHolder) {
if (mOnItemSwipeListener != null && itemSwipeEnabled) {
mOnItemSwipeListener.clearView(viewHolder, getViewHolderPosition(viewHolder));
}
}
public void onItemSwiped(RecyclerView.ViewHolder viewHolder) {
if (mOnItemSwipeListener != null && itemSwipeEnabled) {
mOnItemSwipeListener.onItemSwiped(viewHolder, getViewHolderPosition(viewHolder));
}
int pos = getViewHolderPosition(viewHolder);
mData.remove(pos);
notifyItemRemoved(viewHolder.getAdapterPosition());
}
public void onItemSwiping(Canvas canvas, RecyclerView.ViewHolder viewHolder, float dX, float dY, boolean isCurrentlyActive) {
if (mOnItemSwipeListener != null && itemSwipeEnabled) {
mOnItemSwipeListener.onItemSwipeMoving(canvas, viewHolder, dX, dY, isCurrentlyActive);
}
}
}

View File

@@ -0,0 +1,65 @@
package com.chad.library.adapter.base;
import android.support.annotation.LayoutRes;
import android.util.SparseArray;
import android.view.ViewGroup;
import com.chad.library.adapter.base.entity.MultiItemEntity;
import java.util.List;
/**
* https://github.com/CymChad/BaseRecyclerViewAdapterHelper
*/
public abstract class BaseMultiItemQuickAdapter<T extends MultiItemEntity, K extends BaseViewHolder> extends BaseQuickAdapter<T, K> {
/**
* layouts indexed with their types
*/
private SparseArray<Integer> layouts;
private static final int DEFAULT_VIEW_TYPE = -0xff;
/**
* Same as QuickAdapter#QuickAdapter(Context,int) but with
* some initialization data.
*
* @param data A new list is created out of this one to avoid mutable list
*/
public BaseMultiItemQuickAdapter( List<T> data) {
super( data);
}
@Override
protected int getDefItemViewType(int position) {
Object item = mData.get(position);
if (item instanceof MultiItemEntity) {
return ((MultiItemEntity)item).getItemType();
}
return DEFAULT_VIEW_TYPE;
}
protected void setDefaultViewTypeLayout(@LayoutRes int layoutResId) {
addItemType(DEFAULT_VIEW_TYPE, layoutResId);
}
@Override
protected K onCreateDefViewHolder(ViewGroup parent, int viewType) {
return createBaseViewHolder(parent, getLayoutId(viewType));
}
private int getLayoutId(int viewType) {
return layouts.get(viewType);
}
protected void addItemType(int type, @LayoutRes int layoutResId) {
if (layouts == null) {
layouts = new SparseArray<>();
}
layouts.put(type, layoutResId);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,59 @@
package com.chad.library.adapter.base;
import android.view.ViewGroup;
import com.chad.library.adapter.base.entity.SectionEntity;
import java.util.List;
/**
* https://github.com/CymChad/BaseRecyclerViewAdapterHelper
*/
public abstract class BaseSectionQuickAdapter<T extends SectionEntity, K extends BaseViewHolder> extends BaseQuickAdapter<T, K> {
protected int mSectionHeadResId;
protected static final int SECTION_HEADER_VIEW = 0x00000444;
/**
* Same as QuickAdapter#QuickAdapter(Context,int) but with
* some initialization data.
*
* @param sectionHeadResId The section head layout id for each item
* @param layoutResId The layout resource id of each item.
* @param data A new list is created out of this one to avoid mutable list
*/
public BaseSectionQuickAdapter( int layoutResId, int sectionHeadResId, List<T> data) {
super(layoutResId, data);
this.mSectionHeadResId = sectionHeadResId;
}
@Override
protected int getDefItemViewType(int position) {
return mData.get(position).isHeader ? SECTION_HEADER_VIEW : 0;
}
@Override
protected K onCreateDefViewHolder(ViewGroup parent, int viewType) {
if (viewType == SECTION_HEADER_VIEW)
return createBaseViewHolder(getItemView(mSectionHeadResId, parent));
return super.onCreateDefViewHolder(parent, viewType);
}
@Override
public void onBindViewHolder(K holder, int positions) {
switch (holder.getItemViewType()) {
case SECTION_HEADER_VIEW:
setFullSpan(holder);
convertHead(holder, mData.get(holder.getLayoutPosition() - getHeaderLayoutCount()));
break;
default:
super.onBindViewHolder(holder, positions);
break;
}
}
protected abstract void convertHead(K helper, T item);
}

View File

@@ -0,0 +1,592 @@
/**
* Copyright 2013 Joan Zapata
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.chad.library.adapter.base;
import android.graphics.Bitmap;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.DrawableRes;
import android.support.annotation.StringRes;
import android.support.v7.widget.RecyclerView;
import android.text.util.Linkify;
import android.util.SparseArray;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.CheckedTextView;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RatingBar;
import android.widget.TextView;
import java.util.HashSet;
import java.util.LinkedHashSet;
/**
* https://github.com/CymChad/BaseRecyclerViewAdapterHelper
*/
public class BaseViewHolder extends RecyclerView.ViewHolder {
/**
* Views indexed with their IDs
*/
private final SparseArray<View> views;
public HashSet<Integer> getNestViews() {
return nestViews;
}
private final HashSet<Integer> nestViews;
private final LinkedHashSet<Integer> childClickViewIds;
private final LinkedHashSet<Integer> itemChildLongClickViewIds;
private BaseQuickAdapter adapter;
public View convertView;
/**
* Package private field to retain the associated user object and detect a change
*/
Object associatedObject;
public BaseViewHolder(final View view) {
super(view);
this.views = new SparseArray<>();
this.childClickViewIds = new LinkedHashSet<>();
this.itemChildLongClickViewIds = new LinkedHashSet<>();
this.nestViews = new HashSet<>();
convertView = view;
}
private int getClickPosition() {
return getLayoutPosition() - adapter.getHeaderLayoutCount();
}
public HashSet<Integer> getItemChildLongClickViewIds() {
return itemChildLongClickViewIds;
}
public HashSet<Integer> getChildClickViewIds() {
return childClickViewIds;
}
public View getConvertView() {
return convertView;
}
/**
* Will set the text of a TextView.
*
* @param viewId The view id.
* @param value The text to put in the text view.
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setText(int viewId, CharSequence value) {
TextView view = getView(viewId);
view.setText(value);
return this;
}
public BaseViewHolder setText(int viewId, @StringRes int strId) {
TextView view = getView(viewId);
view.setText(strId);
return this;
}
/**
* Will set the image of an ImageView from a resource id.
*
* @param viewId The view id.
* @param imageResId The image resource id.
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setImageResource(int viewId, @DrawableRes int imageResId) {
ImageView view = getView(viewId);
view.setImageResource(imageResId);
return this;
}
/**
* Will set background color of a view.
*
* @param viewId The view id.
* @param color A color, not a resource id.
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setBackgroundColor(int viewId, int color) {
View view = getView(viewId);
view.setBackgroundColor(color);
return this;
}
/**
* Will set background of a view.
*
* @param viewId The view id.
* @param backgroundRes A resource to use as a background.
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setBackgroundRes(int viewId, @DrawableRes int backgroundRes) {
View view = getView(viewId);
view.setBackgroundResource(backgroundRes);
return this;
}
/**
* Will set text color of a TextView.
*
* @param viewId The view id.
* @param textColor The text color (not a resource id).
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setTextColor(int viewId, int textColor) {
TextView view = getView(viewId);
view.setTextColor(textColor);
return this;
}
/**
* Will set the image of an ImageView from a drawable.
*
* @param viewId The view id.
* @param drawable The image drawable.
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setImageDrawable(int viewId, Drawable drawable) {
ImageView view = getView(viewId);
view.setImageDrawable(drawable);
return this;
}
/**
* Add an action to set the image of an image view. Can be called multiple times.
*/
public BaseViewHolder setImageBitmap(int viewId, Bitmap bitmap) {
ImageView view = getView(viewId);
view.setImageBitmap(bitmap);
return this;
}
/**
* Add an action to set the alpha of a view. Can be called multiple times.
* Alpha between 0-1.
*/
public BaseViewHolder setAlpha(int viewId, float value) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
getView(viewId).setAlpha(value);
} else {
// Pre-honeycomb hack to set Alpha value
AlphaAnimation alpha = new AlphaAnimation(value, value);
alpha.setDuration(0);
alpha.setFillAfter(true);
getView(viewId).startAnimation(alpha);
}
return this;
}
/**
* Set a view visibility to VISIBLE (true) or GONE (false).
*
* @param viewId The view id.
* @param visible True for VISIBLE, false for GONE.
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setVisible(int viewId, boolean visible) {
View view = getView(viewId);
view.setVisibility(visible ? View.VISIBLE : View.GONE);
return this;
}
/**
* Add links into a TextView.
*
* @param viewId The id of the TextView to linkify.
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder linkify(int viewId) {
TextView view = getView(viewId);
Linkify.addLinks(view, Linkify.ALL);
return this;
}
/**
* Apply the typeface to the given viewId, and enable subpixel rendering.
*/
public BaseViewHolder setTypeface(int viewId, Typeface typeface) {
TextView view = getView(viewId);
view.setTypeface(typeface);
view.setPaintFlags(view.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
return this;
}
/**
* Apply the typeface to all the given viewIds, and enable subpixel rendering.
*/
public BaseViewHolder setTypeface(Typeface typeface, int... viewIds) {
for (int viewId : viewIds) {
TextView view = getView(viewId);
view.setTypeface(typeface);
view.setPaintFlags(view.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
}
return this;
}
/**
* Sets the progress of a ProgressBar.
*
* @param viewId The view id.
* @param progress The progress.
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setProgress(int viewId, int progress) {
ProgressBar view = getView(viewId);
view.setProgress(progress);
return this;
}
/**
* Sets the progress and max of a ProgressBar.
*
* @param viewId The view id.
* @param progress The progress.
* @param max The max value of a ProgressBar.
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setProgress(int viewId, int progress, int max) {
ProgressBar view = getView(viewId);
view.setMax(max);
view.setProgress(progress);
return this;
}
/**
* Sets the range of a ProgressBar to 0...max.
*
* @param viewId The view id.
* @param max The max value of a ProgressBar.
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setMax(int viewId, int max) {
ProgressBar view = getView(viewId);
view.setMax(max);
return this;
}
/**
* Sets the rating (the number of stars filled) of a RatingBar.
*
* @param viewId The view id.
* @param rating The rating.
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setRating(int viewId, float rating) {
RatingBar view = getView(viewId);
view.setRating(rating);
return this;
}
/**
* Sets the rating (the number of stars filled) and max of a RatingBar.
*
* @param viewId The view id.
* @param rating The rating.
* @param max The range of the RatingBar to 0...max.
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setRating(int viewId, float rating, int max) {
RatingBar view = getView(viewId);
view.setMax(max);
view.setRating(rating);
return this;
}
/**
* Sets the on click listener of the view.
*
* @param viewId The view id.
* @param listener The on click listener;
* @return The BaseViewHolder for chaining.
*/
@Deprecated
public BaseViewHolder setOnClickListener(int viewId, View.OnClickListener listener) {
View view = getView(viewId);
view.setOnClickListener(listener);
return this;
}
/**
* add childView id
*
* @param viewId add the child view id can support childview click
* @return if you use adapter bind listener
* @link {(adapter.setOnItemChildClickListener(listener))}
* <p>
* or if you can use recyclerView.addOnItemTouch(listerer) wo also support this menthod
*/
@SuppressWarnings("unchecked")
public BaseViewHolder addOnClickListener(final int viewId) {
childClickViewIds.add(viewId);
final View view = getView(viewId);
if (view != null) {
if (!view.isClickable()) {
view.setClickable(true);
}
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (adapter.getOnItemChildClickListener() != null) {
adapter.getOnItemChildClickListener().onItemChildClick(adapter, v, getClickPosition());
}
}
});
}
return this;
}
/**
* set nestview id
*
* @param viewId add the child view id can support childview click
* @return
*/
public BaseViewHolder setNestView(int viewId) {
addOnClickListener(viewId);
addOnLongClickListener(viewId);
nestViews.add(viewId);
return this;
}
/**
* add long click view id
*
* @param viewId
* @return if you use adapter bind listener
* @link {(adapter.setOnItemChildLongClickListener(listener))}
* <p>
* or if you can use recyclerView.addOnItemTouch(listerer) wo also support this menthod
*/
@SuppressWarnings("unchecked")
public BaseViewHolder addOnLongClickListener(final int viewId) {
itemChildLongClickViewIds.add(viewId);
final View view = getView(viewId);
if (view != null) {
if (!view.isLongClickable()) {
view.setLongClickable(true);
}
view.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (adapter.getOnItemChildLongClickListener() != null) {
return adapter.getOnItemChildLongClickListener().onItemChildLongClick(adapter, v, getClickPosition());
}
return false;
}
});
}
return this;
}
/**
* Sets the on touch listener of the view.
*
* @param viewId The view id.
* @param listener The on touch listener;
* @return The BaseViewHolder for chaining.
*/
@Deprecated
public BaseViewHolder setOnTouchListener(int viewId, View.OnTouchListener listener) {
View view = getView(viewId);
view.setOnTouchListener(listener);
return this;
}
/**
* Sets the on long click listener of the view.
*
* @param viewId The view id.
* @param listener The on long click listener;
* @return The BaseViewHolder for chaining.
* Please use {@link #addOnLongClickListener(int)} (adapter.setOnItemChildLongClickListener(listener))}
*/
@Deprecated
public BaseViewHolder setOnLongClickListener(int viewId, View.OnLongClickListener listener) {
View view = getView(viewId);
view.setOnLongClickListener(listener);
return this;
}
/**
* Sets the listview or gridview's item click listener of the view
*
* @param viewId The view id.
* @param listener The item on click listener;
* @return The BaseViewHolder for chaining.
* Please use {@link #addOnClickListener(int)} (int)} (adapter.setOnItemChildClickListener(listener))}
*/
@Deprecated
public BaseViewHolder setOnItemClickListener(int viewId, AdapterView.OnItemClickListener listener) {
AdapterView view = getView(viewId);
view.setOnItemClickListener(listener);
return this;
}
/**
* Sets the listview or gridview's item long click listener of the view
*
* @param viewId The view id.
* @param listener The item long click listener;
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setOnItemLongClickListener(int viewId, AdapterView.OnItemLongClickListener listener) {
AdapterView view = getView(viewId);
view.setOnItemLongClickListener(listener);
return this;
}
/**
* Sets the listview or gridview's item selected click listener of the view
*
* @param viewId The view id.
* @param listener The item selected click listener;
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setOnItemSelectedClickListener(int viewId, AdapterView.OnItemSelectedListener listener) {
AdapterView view = getView(viewId);
view.setOnItemSelectedListener(listener);
return this;
}
/**
* Sets the on checked change listener of the view.
*
* @param viewId The view id.
* @param listener The checked change listener of compound button.
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setOnCheckedChangeListener(int viewId, CompoundButton.OnCheckedChangeListener listener) {
CompoundButton view = getView(viewId);
view.setOnCheckedChangeListener(listener);
return this;
}
/**
* Sets the tag of the view.
*
* @param viewId The view id.
* @param tag The tag;
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setTag(int viewId, Object tag) {
View view = getView(viewId);
view.setTag(tag);
return this;
}
/**
* Sets the tag of the view.
*
* @param viewId The view id.
* @param key The key of tag;
* @param tag The tag;
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setTag(int viewId, int key, Object tag) {
View view = getView(viewId);
view.setTag(key, tag);
return this;
}
/**
* Sets the checked status of a checkable.
*
* @param viewId The view id.
* @param checked The checked status;
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setChecked(int viewId, boolean checked) {
View view = getView(viewId);
// View unable cast to Checkable
if (view instanceof CompoundButton) {
((CompoundButton) view).setChecked(checked);
} else if (view instanceof CheckedTextView) {
((CheckedTextView) view).setChecked(checked);
}
return this;
}
/**
* Sets the adapter of a adapter view.
*
* @param viewId The view id.
* @param adapter The adapter;
* @return The BaseViewHolder for chaining.
*/
public BaseViewHolder setAdapter(int viewId, Adapter adapter) {
AdapterView view = getView(viewId);
view.setAdapter(adapter);
return this;
}
/**
* Sets the adapter of a adapter view.
*
* @param adapter The adapter;
* @return The BaseViewHolder for chaining.
*/
protected BaseViewHolder setAdapter(BaseQuickAdapter adapter) {
this.adapter = adapter;
return this;
}
@SuppressWarnings("unchecked")
public <T extends View> T getView(int viewId) {
View view = views.get(viewId);
if (view == null) {
view = convertView.findViewById(viewId);
views.put(viewId, view);
}
return (T) view;
}
/**
* Retrieves the last converted object on this view.
*/
public Object getAssociatedObject() {
return associatedObject;
}
/**
* Should be called during convert
*/
public void setAssociatedObject(Object associatedObject) {
this.associatedObject = associatedObject;
}
}

View File

@@ -0,0 +1,28 @@
package com.chad.library.adapter.base.animation;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.view.View;
/**
* https://github.com/CymChad/BaseRecyclerViewAdapterHelper
*/
public class AlphaInAnimation implements BaseAnimation {
private static final float DEFAULT_ALPHA_FROM = 0f;
private final float mFrom;
public AlphaInAnimation() {
this(DEFAULT_ALPHA_FROM);
}
public AlphaInAnimation(float from) {
mFrom = from;
}
@Override
public Animator[] getAnimators(View view) {
return new Animator[]{ObjectAnimator.ofFloat(view, "alpha", mFrom, 1f)};
}
}

View File

@@ -0,0 +1,13 @@
package com.chad.library.adapter.base.animation;
import android.animation.Animator;
import android.view.View;
/**
* https://github.com/CymChad/BaseRecyclerViewAdapterHelper
*/
public interface BaseAnimation {
Animator[] getAnimators(View view);
}

View File

@@ -0,0 +1,30 @@
package com.chad.library.adapter.base.animation;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.view.View;
/**
* https://github.com/CymChad/BaseRecyclerViewAdapterHelper
*/
public class ScaleInAnimation implements BaseAnimation {
private static final float DEFAULT_SCALE_FROM = .5f;
private final float mFrom;
public ScaleInAnimation() {
this(DEFAULT_SCALE_FROM);
}
public ScaleInAnimation(float from) {
mFrom = from;
}
@Override
public Animator[] getAnimators(View view) {
ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", mFrom, 1f);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", mFrom, 1f);
return new ObjectAnimator[] { scaleX, scaleY };
}
}

View File

@@ -0,0 +1,21 @@
package com.chad.library.adapter.base.animation;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.view.View;
/**
* https://github.com/CymChad/BaseRecyclerViewAdapterHelper
*/
public class SlideInBottomAnimation implements BaseAnimation {
@Override
public Animator[] getAnimators(View view) {
return new Animator[]{
ObjectAnimator.ofFloat(view, "translationY", view.getMeasuredHeight(), 0)
};
}
}

View File

@@ -0,0 +1,20 @@
package com.chad.library.adapter.base.animation;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.view.View;
/**
* https://github.com/CymChad/BaseRecyclerViewAdapterHelper
*/
public class SlideInLeftAnimation implements BaseAnimation {
@Override
public Animator[] getAnimators(View view) {
return new Animator[] {
ObjectAnimator.ofFloat(view, "translationX", -view.getRootView().getWidth(), 0)
};
}
}

View File

@@ -0,0 +1,20 @@
package com.chad.library.adapter.base.animation;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.view.View;
/**
* https://github.com/CymChad/BaseRecyclerViewAdapterHelper
*/
public class SlideInRightAnimation implements BaseAnimation {
@Override
public Animator[] getAnimators(View view) {
return new Animator[]{
ObjectAnimator.ofFloat(view, "translationX", view.getRootView().getWidth(), 0)
};
}
}

View File

@@ -0,0 +1,196 @@
package com.chad.library.adapter.base.callback;
import android.graphics.Canvas;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.View;
import com.chad.library.R;
import com.chad.library.adapter.base.BaseItemDraggableAdapter;
/**
* Created by luoxw on 2016/6/20.
*/
public class ItemDragAndSwipeCallback extends ItemTouchHelper.Callback {
// private static final String TAG = ItemDragAndSwipeCallback.class.getSimpleName();
BaseItemDraggableAdapter mAdapter;
float mMoveThreshold = 0.1f;
float mSwipeThreshold = 0.7f;
int mDragMoveFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
int mSwipeMoveFlags = ItemTouchHelper.END;
public ItemDragAndSwipeCallback(BaseItemDraggableAdapter adapter) {
mAdapter = adapter;
}
@Override
public boolean isLongPressDragEnabled() {
return false;
}
@Override
public boolean isItemViewSwipeEnabled() {
return mAdapter.isItemSwipeEnable();
}
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (actionState == ItemTouchHelper.ACTION_STATE_DRAG
&& !isViewCreateByAdapter(viewHolder)) {
mAdapter.onItemDragStart(viewHolder);
viewHolder.itemView.setTag(R.id.BaseQuickAdapter_dragging_support, true);
} else if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE
&& !isViewCreateByAdapter(viewHolder)) {
mAdapter.onItemSwipeStart(viewHolder);
viewHolder.itemView.setTag(R.id.BaseQuickAdapter_swiping_support, true);
}
super.onSelectedChanged(viewHolder, actionState);
}
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
if (isViewCreateByAdapter(viewHolder)) {
return;
}
if (viewHolder.itemView.getTag(R.id.BaseQuickAdapter_dragging_support) != null
&& (Boolean)viewHolder.itemView.getTag(R.id.BaseQuickAdapter_dragging_support)) {
mAdapter.onItemDragEnd(viewHolder);
viewHolder.itemView.setTag(R.id.BaseQuickAdapter_dragging_support, false);
}
if (viewHolder.itemView.getTag(R.id.BaseQuickAdapter_swiping_support) != null
&& (Boolean)viewHolder.itemView.getTag(R.id.BaseQuickAdapter_swiping_support)) {
mAdapter.onItemSwipeClear(viewHolder);
viewHolder.itemView.setTag(R.id.BaseQuickAdapter_swiping_support, false);
}
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
if (isViewCreateByAdapter(viewHolder)) {
return makeMovementFlags(0, 0);
}
return makeMovementFlags(mDragMoveFlags, mSwipeMoveFlags);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
if (source.getItemViewType() != target.getItemViewType()) {
return false;
} else {
return true;
}
}
@Override
public void onMoved(RecyclerView recyclerView, RecyclerView.ViewHolder source, int fromPos, RecyclerView.ViewHolder target, int toPos, int x, int y) {
super.onMoved(recyclerView, source, fromPos, target, toPos, x, y);
mAdapter.onItemDragMoving(source, target);
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
if (!isViewCreateByAdapter(viewHolder)) {
mAdapter.onItemSwiped(viewHolder);
}
}
@Override
public float getMoveThreshold(RecyclerView.ViewHolder viewHolder) {
return mMoveThreshold;
}
@Override
public float getSwipeThreshold(RecyclerView.ViewHolder viewHolder) {
return mSwipeThreshold;
}
/**
* Set the fraction that the user should move the View to be considered as swiped.
* The fraction is calculated with respect to RecyclerView's bounds.
* <p>
* Default value is .5f, which means, to swipe a View, user must move the View at least
* half of RecyclerView's width or height, depending on the swipe direction.
*
* @param swipeThreshold A float value that denotes the fraction of the View size. Default value
* is .8f .
*/
public void setSwipeThreshold(float swipeThreshold) {
mSwipeThreshold = swipeThreshold;
}
/**
* Set the fraction that the user should move the View to be considered as it is
* dragged. After a view is moved this amount, ItemTouchHelper starts checking for Views
* below it for a possible drop.
*
* @param moveThreshold A float value that denotes the fraction of the View size. Default value is
* .1f .
*/
public void setMoveThreshold(float moveThreshold) {
mMoveThreshold = moveThreshold;
}
/**
* <p>Set the drag movement direction.</p>
* <p>The value should be ItemTouchHelper.UP, ItemTouchHelper.DOWN, ItemTouchHelper.LEFT, ItemTouchHelper.RIGHT or their combination.</p>
* You can combine them like ItemTouchHelper.UP | ItemTouchHelper.DOWN, it means that the item could only move up and down when dragged.
* @param dragMoveFlags the drag movement direction. Default value is ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT.
*/
public void setDragMoveFlags(int dragMoveFlags) {
mDragMoveFlags = dragMoveFlags;
}
/**
* <p>Set the swipe movement direction.</p>
* <p>The value should be ItemTouchHelper.START, ItemTouchHelper.END or their combination.</p>
* You can combine them like ItemTouchHelper.START | ItemTouchHelper.END, it means that the item could swipe to both left or right.
* @param swipeMoveFlags the swipe movement direction. Default value is ItemTouchHelper.END.
*/
public void setSwipeMoveFlags(int swipeMoveFlags) {
mSwipeMoveFlags = swipeMoveFlags;
}
@Override
public void onChildDrawOver(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
float dX, float dY, int actionState, boolean isCurrentlyActive) {
super.onChildDrawOver(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE
&& !isViewCreateByAdapter(viewHolder)) {
View itemView = viewHolder.itemView;
c.save();
if (dX > 0) {
c.clipRect(itemView.getLeft(), itemView.getTop(),
itemView.getLeft() + dX, itemView.getBottom());
c.translate(itemView.getLeft(), itemView.getTop());
} else {
c.clipRect(itemView.getRight() + dX, itemView.getTop(),
itemView.getRight(), itemView.getBottom());
c.translate(itemView.getRight() + dX, itemView.getTop());
}
mAdapter.onItemSwiping(c, viewHolder, dX, dY, isCurrentlyActive);
c.restore();
}
}
private boolean isViewCreateByAdapter(RecyclerView.ViewHolder viewHolder) {
int type = viewHolder.getItemViewType();
if (type == mAdapter.HEADER_VIEW || type == mAdapter.LOADING_VIEW
|| type == mAdapter.FOOTER_VIEW || type == mAdapter.EMPTY_VIEW) {
return true;
}
return false;
}
}

View File

@@ -0,0 +1,80 @@
package com.chad.library.adapter.base.entity;
import java.util.ArrayList;
import java.util.List;
/**
* <p>A helper to implement expandable item.</p>
* <p>if you don't want to extent a class, you can also implement the interface IExpandable</p>
* Created by luoxw on 2016/8/9.
*/
public abstract class AbstractExpandableItem<T> implements IExpandable<T> {
protected boolean mExpandable = false;
protected List<T> mSubItems;
@Override
public boolean isExpanded() {
return mExpandable;
}
@Override
public void setExpanded(boolean expanded) {
mExpandable = expanded;
}
@Override
public List<T> getSubItems() {
return mSubItems;
}
public boolean hasSubItem() {
return mSubItems != null && mSubItems.size() > 0;
}
public void setSubItems(List<T> list) {
mSubItems = list;
}
public T getSubItem(int position) {
if (hasSubItem() && position < mSubItems.size()) {
return mSubItems.get(position);
} else {
return null;
}
}
public int getSubItemPosition(T subItem) {
return mSubItems != null ? mSubItems.indexOf(subItem) : -1;
}
public void addSubItem(T subItem) {
if (mSubItems == null) {
mSubItems = new ArrayList<>();
}
mSubItems.add(subItem);
}
public void addSubItem(int position, T subItem) {
if (mSubItems != null && position >= 0 && position < mSubItems.size()) {
mSubItems.add(position, subItem);
} else {
addSubItem(subItem);
}
}
public boolean contains(T subItem) {
return mSubItems != null && mSubItems.contains(subItem);
}
public boolean removeSubItem(T subItem) {
return mSubItems != null && mSubItems.remove(subItem);
}
public boolean removeSubItem(int position) {
if (mSubItems != null && position >= 0 && position < mSubItems.size()) {
mSubItems.remove(position);
return true;
}
return false;
}
}

View File

@@ -0,0 +1,19 @@
package com.chad.library.adapter.base.entity;
import java.util.List;
/**
* implement the interface if the item is expandable
* Created by luoxw on 2016/8/8.
*/
public interface IExpandable<T> {
boolean isExpanded();
void setExpanded(boolean expanded);
List<T> getSubItems();
/**
* Get the level of this item. The level start from 0.
* If you don't care about the level, just return a negative.
*/
int getLevel();
}

View File

@@ -0,0 +1,10 @@
package com.chad.library.adapter.base.entity;
/**
* https://github.com/CymChad/BaseRecyclerViewAdapterHelper
*/
public interface MultiItemEntity {
int getItemType();
}

View File

@@ -0,0 +1,22 @@
package com.chad.library.adapter.base.entity;
/**
* https://github.com/CymChad/BaseRecyclerViewAdapterHelper
*/
public abstract class SectionEntity<T> {
public boolean isHeader;
public T t;
public String header;
public SectionEntity(boolean isHeader, String header) {
this.isHeader = isHeader;
this.header = header;
this.t = null;
}
public SectionEntity(T t) {
this.isHeader = false;
this.header = null;
this.t = t;
}
}

View File

@@ -0,0 +1,38 @@
package com.chad.library.adapter.base.listener;
import android.view.View;
import com.chad.library.adapter.base.BaseQuickAdapter;
/**
* Created by AllenCoder on 2016/8/03.
* A convenience class to extend when you only want to OnItemChildClickListener for a subset
* of all the SimpleClickListener. This implements all methods in the
* {@link SimpleClickListener}
**/
public abstract class OnItemChildClickListener extends SimpleClickListener {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
}
@Override
public void onItemLongClick(BaseQuickAdapter adapter, View view, int position) {
}
@Override
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
onSimpleItemChildClick(adapter, view, position);
}
@Override
public void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) {
}
public abstract void onSimpleItemChildClick(BaseQuickAdapter adapter, View view, int position);
}

View File

@@ -0,0 +1,36 @@
package com.chad.library.adapter.base.listener;
import android.view.View;
import com.chad.library.adapter.base.BaseQuickAdapter;
/**
* Created by AllenCoder on 2016/8/03.
* A convenience class to extend when you only want to OnItemChildLongClickListener for a subset
* of all the SimpleClickListener. This implements all methods in the
* {@link SimpleClickListener}
**/
public abstract class OnItemChildLongClickListener extends SimpleClickListener {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
}
@Override
public void onItemLongClick(BaseQuickAdapter adapter, View view, int position) {
}
@Override
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
}
@Override
public void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) {
onSimpleItemChildLongClick(adapter,view,position);
}
public abstract void onSimpleItemChildLongClick(BaseQuickAdapter adapter, View view, int position);
}

View File

@@ -0,0 +1,38 @@
package com.chad.library.adapter.base.listener;
import android.view.View;
import com.chad.library.adapter.base.BaseQuickAdapter;
/**
* Created by AllenCoder on 2016/8/03.
*
*
* A convenience class to extend when you only want to OnItemClickListener for a subset
* of all the SimpleClickListener. This implements all methods in the
* {@link SimpleClickListener}
*/
public abstract class OnItemClickListener extends SimpleClickListener {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
onSimpleItemClick(adapter,view,position);
}
@Override
public void onItemLongClick(BaseQuickAdapter adapter, View view, int position) {
}
@Override
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
}
@Override
public void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) {
}
public abstract void onSimpleItemClick(BaseQuickAdapter adapter, View view, int position);
}

View File

@@ -0,0 +1,13 @@
package com.chad.library.adapter.base.listener;
import android.support.v7.widget.RecyclerView;
/**
* Created by luoxw on 2016/6/20.
*/
public interface OnItemDragListener {
void onItemDragStart(RecyclerView.ViewHolder viewHolder, int pos);
void onItemDragMoving(RecyclerView.ViewHolder source, int from, RecyclerView.ViewHolder target, int to);
void onItemDragEnd(RecyclerView.ViewHolder viewHolder, int pos);
}

View File

@@ -0,0 +1,35 @@
package com.chad.library.adapter.base.listener;
import android.view.View;
import com.chad.library.adapter.base.BaseQuickAdapter;
/**
* create by: allen on 16/8/3.
*/
public abstract class OnItemLongClickListener extends SimpleClickListener {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
}
@Override
public void onItemLongClick(BaseQuickAdapter adapter, View view, int position) {
onSimpleItemLongClick( adapter, view, position);
}
@Override
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
}
@Override
public void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) {
}
public abstract void onSimpleItemLongClick(BaseQuickAdapter adapter, View view, int position);
}

View File

@@ -0,0 +1,39 @@
package com.chad.library.adapter.base.listener;
import android.graphics.Canvas;
import android.support.v7.widget.RecyclerView;
/**
* Created by luoxw on 2016/6/23.
*/
public interface OnItemSwipeListener {
/**
* Called when the swipe action start.
*/
void onItemSwipeStart(RecyclerView.ViewHolder viewHolder, int pos);
/**
* Called when the swipe action is over.
* If you change the view on the start, you should reset is here, no matter the item has swiped or not.
* @param pos If the view is swiped, pos will be negative.
*/
void clearView(RecyclerView.ViewHolder viewHolder, int pos);
/**
* Called when item is swiped, the view is going to be removed from the adapter.
*/
void onItemSwiped(RecyclerView.ViewHolder viewHolder, int pos);
/**
* Draw on the empty edge when swipe moving
* @param canvas the empty edge's canvas
* @param viewHolder The ViewHolder which is being interacted by the User or it was
* interacted and simply animating to its original position
* @param dX The amount of horizontal displacement caused by user's action
* @param dY The amount of vertical displacement caused by user's action
* @param isCurrentlyActive True if this view is currently being controlled by the user or
* false it is simply animating back to its original state.
*/
void onItemSwipeMoving(Canvas canvas, RecyclerView.ViewHolder viewHolder, float dX, float dY, boolean isCurrentlyActive);
}

View File

@@ -0,0 +1,301 @@
package com.chad.library.adapter.base.listener;
import android.os.Build;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import java.util.Set;
import static com.chad.library.adapter.base.BaseQuickAdapter.EMPTY_VIEW;
import static com.chad.library.adapter.base.BaseQuickAdapter.FOOTER_VIEW;
import static com.chad.library.adapter.base.BaseQuickAdapter.HEADER_VIEW;
import static com.chad.library.adapter.base.BaseQuickAdapter.LOADING_VIEW;
/**
* Created by AllenCoder on 2016/8/03.
* <p>
* This can be useful for applications that wish to implement various forms of click and longclick and childView click
* manipulation of item views within the RecyclerView. SimpleClickListener may intercept
* a touch interaction already in progress even if the SimpleClickListener is already handling that
* gesture stream itself for the purposes of scrolling.
*
* @see RecyclerView.OnItemTouchListener
*/
public abstract class SimpleClickListener implements RecyclerView.OnItemTouchListener {
private GestureDetectorCompat mGestureDetector;
private RecyclerView recyclerView;
protected BaseQuickAdapter baseQuickAdapter;
public static String TAG = "SimpleClickListener";
private boolean mIsPrepressed = false;
private boolean mIsShowPress = false;
private View mPressedView = null;
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
if (recyclerView == null) {
this.recyclerView = rv;
this.baseQuickAdapter = (BaseQuickAdapter) recyclerView.getAdapter();
mGestureDetector = new GestureDetectorCompat(recyclerView.getContext(), new ItemTouchHelperGestureListener(recyclerView));
}else if (recyclerView!=rv){
this.recyclerView = rv;
this.baseQuickAdapter = (BaseQuickAdapter) recyclerView.getAdapter();
mGestureDetector = new GestureDetectorCompat(recyclerView.getContext(), new ItemTouchHelperGestureListener(recyclerView));
}
if (!mGestureDetector.onTouchEvent(e) && e.getActionMasked() == MotionEvent.ACTION_UP && mIsShowPress) {
if (mPressedView!=null){
BaseViewHolder vh = (BaseViewHolder) recyclerView.getChildViewHolder(mPressedView);
if (vh == null ||!isHeaderOrFooterView(vh.getItemViewType())) {
mPressedView.setPressed(false);
}
}
mIsShowPress = false;
mIsPrepressed = false;
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
mGestureDetector.onTouchEvent(e);
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener {
private RecyclerView recyclerView;
@Override
public boolean onDown(MotionEvent e) {
mIsPrepressed = true;
mPressedView = recyclerView.findChildViewUnder(e.getX(), e.getY());
super.onDown(e);
return false;
}
@Override
public void onShowPress(MotionEvent e) {
if (mIsPrepressed && mPressedView != null) {
// mPressedView.setPressed(true);
mIsShowPress = true;
}
super.onShowPress(e);
}
ItemTouchHelperGestureListener(RecyclerView recyclerView) {
this.recyclerView = recyclerView;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
if (mIsPrepressed && mPressedView != null) {
if (recyclerView.getScrollState()!=RecyclerView.SCROLL_STATE_IDLE){
return false;
}
final View pressedView = mPressedView;
BaseViewHolder vh = (BaseViewHolder) recyclerView.getChildViewHolder(pressedView);
if (isHeaderOrFooterPosition(vh.getLayoutPosition())) {
return false;
}
Set<Integer> childClickViewIds = vh.getChildClickViewIds();
Set<Integer> nestViewIds = vh.getNestViews();
if (childClickViewIds != null && childClickViewIds.size() > 0) {
for (Integer childClickViewId : childClickViewIds) {
View childView = pressedView.findViewById(childClickViewId);
if (childView != null) {
if (inRangeOfView(childView, e) && childView.isEnabled()) {
if (nestViewIds!=null&&nestViewIds.contains(childClickViewId)){
return false;
}
setPressViewHotSpot(e, childView);
childView.setPressed(true);
onItemChildClick(baseQuickAdapter, childView, vh.getLayoutPosition() - baseQuickAdapter.getHeaderLayoutCount());
resetPressedView(childView);
return true;
} else {
childView.setPressed(false);
}
}
}
setPressViewHotSpot(e,pressedView);
mPressedView.setPressed(true);
for (Integer childClickViewId : childClickViewIds) {
View childView = pressedView.findViewById(childClickViewId);
if (childView!=null){
childView.setPressed(false);
}
}
onItemClick(baseQuickAdapter, pressedView, vh.getLayoutPosition() - baseQuickAdapter.getHeaderLayoutCount());
} else {
setPressViewHotSpot(e,pressedView);
mPressedView.setPressed(true);
if (childClickViewIds != null && childClickViewIds.size() > 0) {
for (Integer childClickViewId : childClickViewIds) {
View childView = pressedView.findViewById(childClickViewId);
if (childView!=null){
childView.setPressed(false);
}
}
}
onItemClick(baseQuickAdapter, pressedView, vh.getLayoutPosition() - baseQuickAdapter.getHeaderLayoutCount());
}
resetPressedView(pressedView);
}
return true;
}
private void resetPressedView(final View pressedView) {
if (pressedView!=null){
pressedView.postDelayed(new Runnable() {
@Override
public void run() {
if (pressedView!=null){
pressedView.setPressed(false);
}
}
},50);
}
mIsPrepressed = false;
mPressedView = null;
}
@Override
public void onLongPress(MotionEvent e) {
boolean isChildLongClick =false;
if (recyclerView.getScrollState()!=RecyclerView.SCROLL_STATE_IDLE){
return ;
}
if (mIsPrepressed && mPressedView != null) {
mPressedView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
BaseViewHolder vh = (BaseViewHolder) recyclerView.getChildViewHolder(mPressedView);
if (!isHeaderOrFooterPosition(vh.getLayoutPosition())) {
Set<Integer> longClickViewIds = vh.getItemChildLongClickViewIds();
Set<Integer> nestViewIds = vh.getNestViews();
if (longClickViewIds != null && longClickViewIds.size() > 0) {
for (Integer longClickViewId : longClickViewIds) {
View childView = mPressedView.findViewById(longClickViewId);
if (inRangeOfView(childView, e) && childView.isEnabled()) {
if (nestViewIds!=null&&nestViewIds.contains(longClickViewId)){
isChildLongClick=true;
break;
}
setPressViewHotSpot(e, childView);
onItemChildLongClick(baseQuickAdapter, childView, vh.getLayoutPosition() - baseQuickAdapter.getHeaderLayoutCount());
childView.setPressed(true);
mIsShowPress = true;
isChildLongClick = true;
break;
}
}
}
if (!isChildLongClick){
onItemLongClick(baseQuickAdapter, mPressedView, vh.getLayoutPosition() - baseQuickAdapter.getHeaderLayoutCount());
setPressViewHotSpot(e,mPressedView);
mPressedView.setPressed(true);
if (longClickViewIds != null) {
for (Integer longClickViewId : longClickViewIds) {
View childView = mPressedView.findViewById(longClickViewId);
childView.setPressed(false);
}
}
mIsShowPress = true;
}
}
}
}
}
private void setPressViewHotSpot(final MotionEvent e,final View mPressedView) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
/**
* when click Outside the region ,mPressedView is null
*/
if (mPressedView !=null && mPressedView.getBackground() != null) {
mPressedView.getBackground().setHotspot(e.getRawX(), e.getY()-mPressedView.getY());
}
}
}
/**
* Callback method to be invoked when an item in this AdapterView has
* been clicked.
*
* @param view The view within the AdapterView that was clicked (this
* will be a view provided by the adapter)
* @param position The position of the view in the adapter.
*/
public abstract void onItemClick(BaseQuickAdapter adapter, View view, int position);
/**
* callback method to be invoked when an item in this view has been
* click and held
*
* @param view The view whihin the AbsListView that was clicked
* @param position The position of the view int the adapter
* @return true if the callback consumed the long click ,false otherwise
*/
public abstract void onItemLongClick(BaseQuickAdapter adapter, View view, int position);
public abstract void onItemChildClick(BaseQuickAdapter adapter, View view, int position);
public abstract void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position);
public boolean inRangeOfView(View view, MotionEvent ev) {
int[] location = new int[2];
if (view==null||!view.isShown()){
return false;
}
view.getLocationOnScreen(location);
int x = location[0];
int y = location[1];
if (ev.getRawX() < x
|| ev.getRawX() > (x + view.getWidth())
|| ev.getRawY() < y
|| ev.getRawY() > (y + view.getHeight())) {
return false;
}
return true;
}
private boolean isHeaderOrFooterPosition(int position) {
/**
* have a headview and EMPTY_VIEW FOOTER_VIEW LOADING_VIEW
*/
if (baseQuickAdapter==null){
if (recyclerView!=null){
baseQuickAdapter= (BaseQuickAdapter) recyclerView.getAdapter();
}else {
return false;
}
}
int type = baseQuickAdapter.getItemViewType(position);
return (type == EMPTY_VIEW || type == HEADER_VIEW || type == FOOTER_VIEW || type == LOADING_VIEW);
}
private boolean isHeaderOrFooterView(int type) {
return (type == EMPTY_VIEW || type == HEADER_VIEW || type == FOOTER_VIEW || type == LOADING_VIEW);
}
}

View File

@@ -0,0 +1,116 @@
package com.chad.library.adapter.base.loadmore;
import android.support.annotation.IdRes;
import android.support.annotation.LayoutRes;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
/**
* Created by BlingBling on 2016/11/11.
*/
public abstract class LoadMoreView {
public static final int STATUS_DEFAULT = 1;
public static final int STATUS_LOADING = 2;
public static final int STATUS_FAIL = 3;
public static final int STATUS_END = 4;
private int mLoadMoreStatus = STATUS_DEFAULT;
private boolean mLoadMoreEndGone = false;
public void setLoadMoreStatus(int loadMoreStatus) {
this.mLoadMoreStatus = loadMoreStatus;
}
public int getLoadMoreStatus() {
return mLoadMoreStatus;
}
public void convert(BaseViewHolder holder) {
switch (mLoadMoreStatus) {
case STATUS_LOADING:
visibleLoading(holder, true);
visibleLoadFail(holder, false);
visibleLoadEnd(holder, false);
break;
case STATUS_FAIL:
visibleLoading(holder, false);
visibleLoadFail(holder, true);
visibleLoadEnd(holder, false);
break;
case STATUS_END:
visibleLoading(holder, false);
visibleLoadFail(holder, false);
visibleLoadEnd(holder, true);
break;
case STATUS_DEFAULT:
visibleLoading(holder, false);
visibleLoadFail(holder, false);
visibleLoadEnd(holder, false);
break;
}
}
private void visibleLoading(BaseViewHolder holder, boolean visible) {
holder.setVisible(getLoadingViewId(), visible);
}
private void visibleLoadFail(BaseViewHolder holder, boolean visible) {
holder.setVisible(getLoadFailViewId(), visible);
}
private void visibleLoadEnd(BaseViewHolder holder, boolean visible) {
final int loadEndViewId=getLoadEndViewId();
if (loadEndViewId != 0) {
holder.setVisible(loadEndViewId, visible);
}
}
public final void setLoadMoreEndGone(boolean loadMoreEndGone) {
this.mLoadMoreEndGone = loadMoreEndGone;
}
public final boolean isLoadEndMoreGone(){
if(getLoadEndViewId()==0){
return true;
}
return mLoadMoreEndGone;}
/**
* No more data is hidden
* @return true for no more data hidden load more
* @deprecated Use {@link BaseQuickAdapter#loadMoreEnd(boolean)} instead.
*/
@Deprecated
public boolean isLoadEndGone(){return mLoadMoreEndGone;}
/**
* load more layout
*
* @return
*/
public abstract @LayoutRes int getLayoutId();
/**
* loading view
*
* @return
*/
protected abstract @IdRes int getLoadingViewId();
/**
* load fail view
*
* @return
*/
protected abstract @IdRes int getLoadFailViewId();
/**
* load end view, you can return 0
*
* @return
*/
protected abstract @IdRes int getLoadEndViewId();
}

View File

@@ -0,0 +1,27 @@
package com.chad.library.adapter.base.loadmore;
import com.chad.library.R;
/**
* Created by BlingBling on 2016/10/11.
*/
public final class SimpleLoadMoreView extends LoadMoreView {
@Override public int getLayoutId() {
return R.layout.quick_view_load_more;
}
@Override protected int getLoadingViewId() {
return R.id.load_more_loading_view;
}
@Override protected int getLoadFailViewId() {
return R.id.load_more_load_fail_view;
}
@Override protected int getLoadEndViewId() {
return R.id.load_more_load_end_view;
}
}

View File

@@ -0,0 +1,90 @@
package com.chad.library.adapter.base.util;
import android.support.annotation.LayoutRes;
import android.util.SparseIntArray;
import java.util.List;
/**
* help you to achieve multi type easily
* <p>
* Created by tysheng
* Date: 2017/4/6 08:41.
* Email: tyshengsx@gmail.com
* <p>
*
* more information: https://github.com/CymChad/BaseRecyclerViewAdapterHelper/issues/968
*/
public abstract class MultiTypeDelegate<T> {
private static final int DEFAULT_VIEW_TYPE = -0xff;
private SparseIntArray layouts;
private boolean autoMode, selfMode;
public MultiTypeDelegate(SparseIntArray layouts) {
this.layouts = layouts;
}
public MultiTypeDelegate() {
}
public final int getDefItemViewType(List<T> data, int position) {
T item = data.get(position);
return item != null ? getItemType(item) : DEFAULT_VIEW_TYPE;
}
/**
* get the item type from specific entity.
*
* @param t entity
* @return item type
*/
protected abstract int getItemType(T t);
public final int getLayoutId(int viewType) {
return this.layouts.get(viewType);
}
private void addItemType(int type, @LayoutRes int layoutResId) {
if (this.layouts == null) {
this.layouts = new SparseIntArray();
}
this.layouts.put(type, layoutResId);
}
/**
* auto increase type vale, start from 0.
*
* @param layoutResIds layout id arrays
* @return MultiTypeDelegate
*/
public MultiTypeDelegate registerItemTypeAutoIncrease(@LayoutRes int... layoutResIds) {
autoMode = true;
checkMode(selfMode);
for (int i = 0; i < layoutResIds.length; i++) {
addItemType(i, layoutResIds[i]);
}
return this;
}
/**
* set your own type one by one.
*
* @param type type value
* @param layoutResId layout id
* @return MultiTypeDelegate
*/
public MultiTypeDelegate registerItemType(int type, @LayoutRes int layoutResId) {
selfMode = true;
checkMode(autoMode);
addItemType(type, layoutResId);
return this;
}
private void checkMode(boolean mode) {
if (mode) {
throw new RuntimeException("Don't mess two register mode");
}
}
}

View File

@@ -0,0 +1,29 @@
package com.chad.library.adapter.base.util;
import android.view.MotionEvent;
public class TouchEventUtil {
public static String getTouchAction(int actionId) {
String actionName = "Unknow:id=" + actionId;
switch (actionId) {
case MotionEvent.ACTION_DOWN:
actionName = "ACTION_DOWN";
break;
case MotionEvent.ACTION_MOVE:
actionName = "ACTION_MOVE";
break;
case MotionEvent.ACTION_UP:
actionName = "ACTION_UP";
break;
case MotionEvent.ACTION_CANCEL:
actionName = "ACTION_CANCEL";
break;
case MotionEvent.ACTION_OUTSIDE:
actionName = "ACTION_OUTSIDE";
break;
}
return actionName;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<rotate
android:drawable="@drawable/sample_footer_loading"
android:duration="500"
android:fromDegrees="0.0"
android:pivotX="50.0%"
android:pivotY="50.0%"
android:toDegrees="360.0" />
</item>
</layer-list>

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_40">
<LinearLayout
android:id="@+id/load_more_loading_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal">
<ProgressBar
android:id="@+id/loading_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleSmall"
android:layout_marginRight="@dimen/dp_4"/>
<TextView
android:id="@+id/loading_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_4"
android:text="@string/loading"
android:textColor="@android:color/black"
android:textSize="@dimen/sp_14"/>
</LinearLayout>
<FrameLayout
android:id="@+id/load_more_load_fail_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<TextView
android:id="@+id/tv_prompt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/load_failed"/>
</FrameLayout>
<FrameLayout
android:id="@+id/load_more_load_end_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/load_end"
android:textColor="@android:color/darker_gray"/>
</FrameLayout>
</FrameLayout>

View File

@@ -0,0 +1,5 @@
<resources>
<string name="loading">Loading...</string>
<string name="load_failed">load more failed</string>
<string name="load_end">No more data</string>
</resources>

View File

@@ -0,0 +1,13 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="def_height">50dp</dimen>
<dimen name="dp_4">4dp</dimen>
<dimen name="dp_10">10dp</dimen>
<dimen name="dp_40">40dp</dimen>
<dimen name="dp_72">72dp</dimen>
<dimen name="sp_12">12sp</dimen>
<dimen name="sp_14">14sp</dimen>
<dimen name="sp_16">16sp</dimen>
</resources>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="BaseQuickAdapter_viewholder_support" type="id"/>
<item name="BaseQuickAdapter_swiping_support" type="id"/>
<item name="BaseQuickAdapter_dragging_support" type="id"/>
<item name="BaseQuickAdapter_databinding_support" type="id"/>
</resources>

View File

@@ -0,0 +1,6 @@
<resources>
<string name="app_name">Library</string>
<string name="loading">正在加载中...</string>
<string name="load_failed">加载失败,请点我重试</string>
<string name="load_end">没有更多数据</string>
</resources>