+ *
+ * A listener will be attached to the button which will
+ * either expand or collapse the expandable view
+ *
+ * @see #getExpandableView(View)
+ * @param parent the list view item
+ * @ensure return!=null
+ * @return a child of parent which is a button
+ */
+ public abstract View getExpandToggleButton(View parent);
+
+ /**
+ * This method is used to get the view that will be hidden
+ * initially and expands or collapse when the ExpandToggleButton
+ * is pressed @see getExpandToggleButton
+ *
+ * Normally it will be implemented as:
+ *
+ */
+public class BaseAdapterHelper {
+
+ /** Views indexed with their IDs */
+ private final SparseArray views;
+
+ private final Context context;
+
+ private int position;
+
+ private View convertView;
+
+ /** Package private field to retain the associated user object and detect a change */
+ Object associatedObject;
+
+ private BaseAdapterHelper(Context context, ViewGroup parent, int layoutId, int position) {
+ this.context = context;
+ this.position = position;
+ this.views = new SparseArray();
+ convertView = LayoutInflater.from(context) //
+ .inflate(layoutId, parent, false);
+ convertView.setTag(this);
+ }
+
+ /**
+ * This method is the only entry point to get a BaseAdapterHelper.
+ * @param context The current context.
+ * @param convertView The convertView arg passed to the getView() method.
+ * @param parent The parent arg passed to the getView() method.
+ * @return A BaseAdapterHelper instance.
+ */
+ public static BaseAdapterHelper get(Context context, View convertView, ViewGroup parent, int layoutId) {
+ return get(context, convertView, parent, layoutId, -1);
+ }
+
+ /** This method is package private and should only be used by QuickAdapter. */
+ static BaseAdapterHelper get(Context context, View convertView, ViewGroup parent, int layoutId, int position) {
+ if (convertView == null) {
+ return new BaseAdapterHelper(context, parent, layoutId, position);
+ }
+
+ // Retrieve the existing helper and update its position
+ BaseAdapterHelper existingHelper = (BaseAdapterHelper) convertView.getTag();
+ existingHelper.position = position;
+ return existingHelper;
+ }
+
+ /**
+ * This method allows you to retrieve a view and perform custom
+ * operations on it, not covered by the BaseAdapterHelper.
+ * If you think it's a common use case, please consider creating
+ * a new issue at https://github.com/JoanZapata/base-adapter-helper/issues.
+ * @param viewId The id of the view you want to retrieve.
+ */
+ public T getView(int viewId) {
+ return retrieveView(viewId);
+ }
+
+ /**
+ * Will set the text of a TextView.
+ * @param viewId The view id.
+ * @param value The text to put in the text view.
+ * @return The BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setText(int viewId, String value) {
+ TextView view = retrieveView(viewId);
+ view.setText(value);
+ 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 BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setImageResource(int viewId, int imageResId) {
+ ImageView view = retrieveView(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 BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setBackgroundColor(int viewId, int color) {
+ View view = retrieveView(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 BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setBackgroundRes(int viewId, int backgroundRes) {
+ View view = retrieveView(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 BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setTextColor(int viewId, int textColor) {
+ TextView view = retrieveView(viewId);
+ view.setTextColor(textColor);
+ return this;
+ }
+
+ /**
+ * Will set text color of a TextView.
+ * @param viewId The view id.
+ * @param textColorRes The text color resource id.
+ * @return The BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setTextColorRes(int viewId, int textColorRes) {
+ TextView view = retrieveView(viewId);
+ view.setTextColor(context.getResources().getColor(textColorRes));
+ return this;
+ }
+
+ /**
+ * Will set the image of an ImageView from a drawable.
+ * @param viewId The view id.
+ * @param drawable The image drawable.
+ * @return The BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setImageDrawable(int viewId, Drawable drawable) {
+ ImageView view = retrieveView(viewId);
+ view.setImageDrawable(drawable);
+ return this;
+ }
+
+ /**
+ * Will download an image from a URL and put it in an ImageView.
+ * It uses Square's Picasso library to download the image asynchronously and put the result into the ImageView.
+ * Picasso manages recycling of views in a ListView.
+ * If you need more control over the Picasso settings, use {BaseAdapterHelper#setImageBuilder}.
+ * @param viewId The view id.
+ * @param imageUrl The image URL.
+ * @return The BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setImageUrl(int viewId, String imageUrl) {
+ ImageView view = retrieveView(viewId);
+ Picasso.with(context).load(imageUrl).into(view);
+ return this;
+ }
+
+ /**
+ * Will download an image from a URL and put it in an ImageView.
+ * @param viewId The view id.
+ * @param requestBuilder The Picasso request builder. (e.g. Picasso.with(context).load(imageUrl))
+ * @return The BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setImageBuilder(int viewId, RequestCreator requestBuilder) {
+ ImageView view = retrieveView(viewId);
+ requestBuilder.into(view);
+ return this;
+ }
+
+ /** Add an action to set the image of an image view. Can be called multiple times. */
+ public BaseAdapterHelper setImageBitmap(int viewId, Bitmap bitmap) {
+ ImageView view = retrieveView(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 BaseAdapterHelper setAlpha(int viewId, float value) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ retrieveView(viewId).setAlpha(value);
+ } else {
+ // Pre-honeycomb hack to set Alpha value
+ AlphaAnimation alpha = new AlphaAnimation(value, value);
+ alpha.setDuration(0);
+ alpha.setFillAfter(true);
+ retrieveView(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 BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setVisible(int viewId, boolean visible) {
+ View view = retrieveView(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 BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper linkify(int viewId) {
+ TextView view = retrieveView(viewId);
+ Linkify.addLinks(view, Linkify.ALL);
+ return this;
+ }
+
+ /** Apply the typeface to the given viewId, and enable subpixel rendering. */
+ public BaseAdapterHelper setTypeface(int viewId, Typeface typeface) {
+ TextView view = retrieveView(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 BaseAdapterHelper setTypeface(Typeface typeface, int... viewIds) {
+ for (int viewId : viewIds) {
+ TextView view = retrieveView(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 BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setProgress(int viewId, int progress) {
+ ProgressBar view = retrieveView(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 BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setProgress(int viewId, int progress, int max) {
+ ProgressBar view = retrieveView(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 BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setMax(int viewId, int max) {
+ ProgressBar view = retrieveView(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 BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setRating(int viewId, float rating) {
+ RatingBar view = retrieveView(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 BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setRating(int viewId, float rating, int max) {
+ RatingBar view = retrieveView(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 BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setOnClickListener(int viewId, View.OnClickListener listener) {
+ View view = retrieveView(viewId);
+ view.setOnClickListener(listener);
+ return this;
+ }
+
+ /**
+ * Sets the on touch listener of the view.
+ * @param viewId The view id.
+ * @param listener The on touch listener;
+ * @return The BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setOnTouchListener(int viewId, View.OnTouchListener listener) {
+ View view = retrieveView(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 BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setOnLongClickListener(int viewId, View.OnLongClickListener listener) {
+ View view = retrieveView(viewId);
+ view.setOnLongClickListener(listener);
+ return this;
+ }
+
+ /**
+ * Sets the tag of the view.
+ * @param viewId The view id.
+ * @param tag The tag;
+ * @return The BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setTag(int viewId, Object tag) {
+ View view = retrieveView(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 BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setTag(int viewId, int key, Object tag) {
+ View view = retrieveView(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 BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setChecked(int viewId, boolean checked) {
+ Checkable view = (Checkable) retrieveView(viewId);
+ view.setChecked(checked);
+ return this;
+ }
+
+ /**
+ * Sets the adapter of a adapter view.
+ * @param viewId The view id.
+ * @param adapter The adapter;
+ * @return The BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setAdapter(int viewId, Adapter adapter) {
+ AdapterView view = retrieveView(viewId);
+ view.setAdapter(adapter);
+ return this;
+ }
+
+ /** Retrieve the convertView */
+ public View getView() {
+ return convertView;
+ }
+
+ /**
+ * Retrieve the overall position of the data in the list.
+ * @throws IllegalArgumentException If the position hasn't been set at the construction of the this helper.
+ */
+ public int getPosition() {
+ if (position == -1)
+ throw new IllegalStateException("Use BaseAdapterHelper constructor " +
+ "with position if you need to retrieve the position.");
+ return position;
+ }
+
+ @SuppressWarnings("unchecked")
+ private T retrieveView(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;
+ }
+}
diff --git a/quick-adapter-demo/app/src/main/java/com/joanzapata/android/BaseQuickAdapter.java b/quick-adapter-demo/app/src/main/java/com/joanzapata/android/BaseQuickAdapter.java
new file mode 100644
index 0000000..06e692f
--- /dev/null
+++ b/quick-adapter-demo/app/src/main/java/com/joanzapata/android/BaseQuickAdapter.java
@@ -0,0 +1,197 @@
+/**
+ * Copyright 2013 Joan Zapata
+ *
+ * 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
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.joanzapata.android;
+
+import android.content.Context;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.FrameLayout;
+import android.widget.ProgressBar;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Abstraction class of a BaseAdapter in which you only need
+ * to provide the convert() implementation.
+ * Using the provided BaseAdapterHelper, your code is minimalist.
+ * @param The type of the items in the list.
+ */
+public abstract class BaseQuickAdapter extends BaseAdapter {
+
+ protected static final String TAG = BaseQuickAdapter.class.getSimpleName();
+
+ protected final Context context;
+
+ protected final int layoutResId;
+
+ protected final List data;
+
+ protected boolean displayIndeterminateProgress = false;
+
+ /**
+ * Create a QuickAdapter.
+ * @param context The context.
+ * @param layoutResId The layout resource id of each item.
+ */
+ public BaseQuickAdapter(Context context, int layoutResId) {
+ this(context, layoutResId, null);
+ }
+
+ /**
+ * Same as QuickAdapter#QuickAdapter(Context,int) but with
+ * some initialization data.
+ * @param context The context.
+ * @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 BaseQuickAdapter(Context context, int layoutResId, List data) {
+ this.data = data == null ? new ArrayList() : new ArrayList(data);
+ this.context = context;
+ this.layoutResId = layoutResId;
+ }
+
+ @Override
+ public int getCount() {
+ int extra = displayIndeterminateProgress ? 1 : 0;
+ return data.size() + extra;
+ }
+
+ @Override
+ public T getItem(int position) {
+ if (position >= data.size()) return null;
+ return data.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return 2;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return position >= data.size() ? 1 : 0;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ if (getItemViewType(position) == 0) {
+ final H helper = getAdapterHelper(position, convertView, parent);
+ T item = getItem(position);
+ helper.setAssociatedObject(item);
+ convert(helper, item);
+ return helper.getView();
+ }
+
+ return createIndeterminateProgressView(convertView, parent);
+ }
+
+ private View createIndeterminateProgressView(View convertView, ViewGroup parent) {
+ if (convertView == null) {
+ FrameLayout container = new FrameLayout(context);
+ container.setForegroundGravity(Gravity.CENTER);
+ ProgressBar progress = new ProgressBar(context);
+ container.addView(progress);
+ convertView = container;
+ }
+ return convertView;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ return position < data.size();
+ }
+
+ public void add(T elem) {
+ data.add(elem);
+ notifyDataSetChanged();
+ }
+
+ public void addAll(List elem) {
+ data.addAll(elem);
+ notifyDataSetChanged();
+ }
+
+ public void set(T oldElem, T newElem) {
+ set(data.indexOf(oldElem), newElem);
+ }
+
+ public void set(int index, T elem) {
+ data.set(index, elem);
+ notifyDataSetChanged();
+ }
+
+ public void remove(T elem) {
+ data.remove(elem);
+ notifyDataSetChanged();
+ }
+
+ public void remove(int index) {
+ data.remove(index);
+ notifyDataSetChanged();
+ }
+
+ public void replaceAll(List elem) {
+ data.clear();
+ data.addAll(elem);
+ notifyDataSetChanged();
+ }
+
+ public boolean contains(T elem) {
+ return data.contains(elem);
+ }
+
+ /** Clear data list */
+ public void clear() {
+ data.clear();
+ notifyDataSetChanged();
+ }
+
+ public void showIndeterminateProgress(boolean display) {
+ if (display == displayIndeterminateProgress) return;
+ displayIndeterminateProgress = display;
+ notifyDataSetChanged();
+ }
+
+ /**
+ * Implement this method and use the helper to adapt the view to the given item.
+ * @param helper A fully initialized helper.
+ * @param item The item that needs to be displayed.
+ */
+ protected abstract void convert(H helper, T item);
+
+ /**
+ * You can override this method to use a custom BaseAdapterHelper in order to fit your needs
+ * @param position The position of the item within the adapter's data set of the item whose view we want.
+ * @param convertView The old view to reuse, if possible. Note: You should check that this view
+ * is non-null and of an appropriate type before using. If it is not possible to convert
+ * this view to display the correct data, this method can create a new view.
+ * Heterogeneous lists can specify their number of view types, so that this View is
+ * always of the right type (see {@link #getViewTypeCount()} and
+ * {@link #getItemViewType(int)}).
+ * @param parent The parent that this view will eventually be attached to
+ * @return An instance of BaseAdapterHelper
+ */
+ protected abstract H getAdapterHelper(int position, View convertView, ViewGroup parent);
+
+}
diff --git a/quick-adapter-demo/app/src/main/java/com/joanzapata/android/EnhancedQuickAdapter.java b/quick-adapter-demo/app/src/main/java/com/joanzapata/android/EnhancedQuickAdapter.java
new file mode 100644
index 0000000..5998482
--- /dev/null
+++ b/quick-adapter-demo/app/src/main/java/com/joanzapata/android/EnhancedQuickAdapter.java
@@ -0,0 +1,53 @@
+package com.joanzapata.android;
+
+import android.content.Context;
+
+import java.util.List;
+
+/**
+ * Same as QuickAdapter, but adds an "itemChanged" boolean in the
+ * convert() method params, which allows you to know if you are
+ * adapting the new view to the same item or not, and therefore
+ * make a difference between dataset changed / dataset invalidated.
+ *
+ * Abstraction class of a BaseAdapter in which you only need
+ * to provide the convert() implementation.
+ * Using the provided BaseAdapterHelper, your code is minimalist.
+ * @param The type of the items in the list.
+ */
+public abstract class EnhancedQuickAdapter extends QuickAdapter {
+
+ /**
+ * Create a QuickAdapter.
+ * @param context The context.
+ * @param layoutResId The layout resource id of each item.
+ */
+ public EnhancedQuickAdapter(Context context, int layoutResId) {
+ super(context, layoutResId);
+ }
+
+ /**
+ * Same as QuickAdapter#QuickAdapter(Context,int) but with
+ * some initialization data.
+ * @param context The context.
+ * @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 EnhancedQuickAdapter(Context context, int layoutResId, List data) {
+ super(context, layoutResId, data);
+ }
+
+ @Override
+ protected final void convert(BaseAdapterHelper helper, T item) {
+ boolean itemChanged = helper.associatedObject == null || !helper.associatedObject.equals(item);
+ helper.associatedObject = item;
+ convert(helper, item, itemChanged);
+ }
+
+ /**
+ * @param helper The helper to use to adapt the view.
+ * @param item The item you should adapt the view to.
+ * @param itemChanged Whether or not the helper was bound to another object before.
+ */
+ protected abstract void convert(BaseAdapterHelper helper, T item, boolean itemChanged);
+}
diff --git a/quick-adapter-demo/app/src/main/java/com/joanzapata/android/QuickAdapter.java b/quick-adapter-demo/app/src/main/java/com/joanzapata/android/QuickAdapter.java
new file mode 100644
index 0000000..f37ec78
--- /dev/null
+++ b/quick-adapter-demo/app/src/main/java/com/joanzapata/android/QuickAdapter.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright 2013 Joan Zapata
+ *
+ * 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
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.joanzapata.android;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.List;
+
+import static com.joanzapata.android.BaseAdapterHelper.get;
+
+/**
+ * Abstraction class of a BaseAdapter in which you only need
+ * to provide the convert() implementation.
+ * Using the provided BaseAdapterHelper, your code is minimalist.
+ * @param The type of the items in the list.
+ */
+public abstract class QuickAdapter extends BaseQuickAdapter {
+
+ /**
+ * Create a QuickAdapter.
+ * @param context The context.
+ * @param layoutResId The layout resource id of each item.
+ */
+ public QuickAdapter(Context context, int layoutResId) {
+ super(context, layoutResId);
+ }
+
+ /**
+ * Same as QuickAdapter#QuickAdapter(Context,int) but with
+ * some initialization data.
+ * @param context The context.
+ * @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 QuickAdapter(Context context, int layoutResId, List data) {
+ super(context, layoutResId, data);
+ }
+
+ protected BaseAdapterHelper getAdapterHelper(int position, View convertView, ViewGroup parent) {
+ return get(context, convertView, parent, layoutResId, position);
+ }
+
+}
diff --git a/quick-adapter-demo/app/src/main/java/com/wmmeng/quickadapterdemo/BaseListViewFragment.java b/quick-adapter-demo/app/src/main/java/com/wmmeng/quickadapterdemo/BaseListViewFragment.java
new file mode 100644
index 0000000..636b218
--- /dev/null
+++ b/quick-adapter-demo/app/src/main/java/com/wmmeng/quickadapterdemo/BaseListViewFragment.java
@@ -0,0 +1,36 @@
+package com.wmmeng.quickadapterdemo;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+
+public abstract class BaseListViewFragment extends Fragment {
+
+ ListView listview;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ initData();
+ }
+
+ public abstract void initData();
+
+ @Override
+ public View onCreateView(LayoutInflater inflater,
+ @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.fragment_listview, null);
+ listview = (ListView) view.findViewById(R.id.listview);
+ listview.setAdapter(getAdapter());
+ return view;
+ }
+
+ protected abstract BaseAdapter getAdapter();
+
+
+}
diff --git a/quick-adapter-demo/app/src/main/java/com/wmmeng/quickadapterdemo/DemoActivity.java b/quick-adapter-demo/app/src/main/java/com/wmmeng/quickadapterdemo/DemoActivity.java
new file mode 100644
index 0000000..1e17dcf
--- /dev/null
+++ b/quick-adapter-demo/app/src/main/java/com/wmmeng/quickadapterdemo/DemoActivity.java
@@ -0,0 +1,29 @@
+package com.wmmeng.quickadapterdemo;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v7.app.ActionBarActivity;
+
+import com.squareup.picasso.Picasso;
+
+public class DemoActivity extends ActionBarActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_demo);
+ initData();
+ }
+
+ private void initData() {
+ FragmentManager fragmentManager = getSupportFragmentManager();
+ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+ String f = getIntent().getStringExtra(MainActivity.KEY);
+ if(SingleLayoutFragment.class.getSimpleName().equals(f)){
+ fragmentTransaction.replace(R.id.lay_container, new SingleLayoutFragment());
+ }else if(PicassoFragment.class.getSimpleName().equals(f)){
+ fragmentTransaction.replace(R.id.lay_container, new PicassoFragment());
+ }
+ fragmentTransaction.commit();
+ }
+}
diff --git a/quick-adapter-demo/app/src/main/java/com/wmmeng/quickadapterdemo/MainActivity.java b/quick-adapter-demo/app/src/main/java/com/wmmeng/quickadapterdemo/MainActivity.java
new file mode 100644
index 0000000..a70204a
--- /dev/null
+++ b/quick-adapter-demo/app/src/main/java/com/wmmeng/quickadapterdemo/MainActivity.java
@@ -0,0 +1,53 @@
+package com.wmmeng.quickadapterdemo;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+public class MainActivity extends ActionBarActivity implements OnClickListener {
+ public static final String KEY = "fragment";
+ private Button btn_single_layout, btn_net_image;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ initView();
+ initListener();
+ }
+
+ private void initView() {
+ btn_single_layout = (Button) findViewById(R.id.btn_single_layout);
+ btn_net_image = (Button) findViewById(R.id.btn_net_image);
+ }
+
+ private void initListener() {
+ btn_single_layout.setOnClickListener(this);
+ btn_net_image.setOnClickListener(this);
+ }
+
+ @Override
+ public void onClick(View view) {
+ Intent intent;
+ switch (view.getId()) {
+ case R.id.btn_single_layout:
+ intent = new Intent(this, DemoActivity.class);
+ intent.putExtra(KEY, SingleLayoutFragment.class.getSimpleName());
+ startActivity(intent);
+
+ break;
+ case R.id.btn_net_image:
+ intent = new Intent(this, DemoActivity.class);
+ intent.putExtra(KEY, PicassoFragment.class.getSimpleName());
+ startActivity(intent);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+}
diff --git a/quick-adapter-demo/app/src/main/java/com/wmmeng/quickadapterdemo/PicassoFragment.java b/quick-adapter-demo/app/src/main/java/com/wmmeng/quickadapterdemo/PicassoFragment.java
new file mode 100644
index 0000000..337d600
--- /dev/null
+++ b/quick-adapter-demo/app/src/main/java/com/wmmeng/quickadapterdemo/PicassoFragment.java
@@ -0,0 +1,42 @@
+package com.wmmeng.quickadapterdemo;
+
+import android.util.Log;
+import android.widget.BaseAdapter;
+
+import com.joanzapata.android.BaseAdapterHelper;
+import com.joanzapata.android.QuickAdapter;
+import com.squareup.picasso.Picasso;
+
+import java.util.ArrayList;
+
+public class PicassoFragment extends BaseListViewFragment {
+ String[] images = {"http://ent.iyaxin.com/attachement/jpg/site2/20110805/0019667873730fa5f54551.jpg",
+ "http://ent.iyaxin.com/attachement/jpg/site2/20110805/0019667873730fa5f68753.jpg",
+ "http://pic1.nipic.com/2008-12-02/200812210427444_2.jpg",
+ "http://www.gog.com.cn/pic/0/11/35/11/11351128_680557.jpg",
+ "http://www.gog.com.cn/pic/0/11/35/11/11351129_248834.jpg",
+ "http://www.gog.com.cn/pic/0/11/35/11/11351131_777144.jpg",
+ };
+ ArrayList data;
+ BaseAdapter adapter;
+ @Override
+ protected BaseAdapter getAdapter() {
+ adapter = new QuickAdapter(getActivity(), R.layout.item_picasso_image, data) {
+ @Override
+ protected void convert(BaseAdapterHelper helper, String item) {
+ Log.i("wmm", item);
+ helper.setImageBuilder(R.id.iv_picasso_image, Picasso.with(getActivity()).load(item));
+ }
+ };
+ return adapter;
+ }
+
+ @Override
+ public void initData() {
+ data = new ArrayList<>();
+ for (int i = 0;i data;
+ BaseAdapter adapter;
+
+ @Override
+ public void initData() {
+ data = new ArrayList();
+ for (int i = 0; i < 50; i++) {
+ data.add("Hello QuickAdapter " + i);
+ }
+ }
+
+ @Override
+ protected BaseAdapter getAdapter() {
+ Log.i("wmm", "getAdapter " + data.size());
+ adapter = new QuickAdapter(getActivity(),
+ R.layout.item_single_layout, data) {
+
+ @Override
+ protected void convert(BaseAdapterHelper helper, String item) {
+ Log.i("wmm", item);
+ helper.setText(R.id.tv_text, item);
+ }
+ };
+ return adapter;
+ }
+}
diff --git a/quick-adapter-demo/app/src/main/res/drawable-hdpi/ic_launcher.png b/quick-adapter-demo/app/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
Binary files /dev/null and b/quick-adapter-demo/app/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/quick-adapter-demo/app/src/main/res/drawable-mdpi/ic_launcher.png b/quick-adapter-demo/app/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
Binary files /dev/null and b/quick-adapter-demo/app/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/quick-adapter-demo/app/src/main/res/drawable-xhdpi/ic_launcher.png b/quick-adapter-demo/app/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
Binary files /dev/null and b/quick-adapter-demo/app/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/quick-adapter-demo/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/quick-adapter-demo/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/quick-adapter-demo/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/quick-adapter-demo/app/src/main/res/layout/activity_demo.xml b/quick-adapter-demo/app/src/main/res/layout/activity_demo.xml
new file mode 100644
index 0000000..1b6044d
--- /dev/null
+++ b/quick-adapter-demo/app/src/main/res/layout/activity_demo.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/quick-adapter-demo/app/src/main/res/layout/activity_main.xml b/quick-adapter-demo/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..d1001f1
--- /dev/null
+++ b/quick-adapter-demo/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/quick-adapter-demo/app/src/main/res/layout/fragment_listview.xml b/quick-adapter-demo/app/src/main/res/layout/fragment_listview.xml
new file mode 100644
index 0000000..af21d1a
--- /dev/null
+++ b/quick-adapter-demo/app/src/main/res/layout/fragment_listview.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/quick-adapter-demo/app/src/main/res/layout/item_picasso_image.xml b/quick-adapter-demo/app/src/main/res/layout/item_picasso_image.xml
new file mode 100644
index 0000000..fc022e3
--- /dev/null
+++ b/quick-adapter-demo/app/src/main/res/layout/item_picasso_image.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
diff --git a/quick-adapter-demo/app/src/main/res/layout/item_single_layout.xml b/quick-adapter-demo/app/src/main/res/layout/item_single_layout.xml
new file mode 100644
index 0000000..6dfc963
--- /dev/null
+++ b/quick-adapter-demo/app/src/main/res/layout/item_single_layout.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/quick-adapter-demo/app/src/main/res/menu/menu_main.xml b/quick-adapter-demo/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..b1cb908
--- /dev/null
+++ b/quick-adapter-demo/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,6 @@
+
diff --git a/quick-adapter-demo/app/src/main/res/values-w820dp/dimens.xml b/quick-adapter-demo/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/quick-adapter-demo/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/quick-adapter-demo/app/src/main/res/values/dimens.xml b/quick-adapter-demo/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..47c8224
--- /dev/null
+++ b/quick-adapter-demo/app/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+
+
+ 16dp
+ 16dp
+
diff --git a/quick-adapter-demo/app/src/main/res/values/strings.xml b/quick-adapter-demo/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..b71607e
--- /dev/null
+++ b/quick-adapter-demo/app/src/main/res/values/strings.xml
@@ -0,0 +1,11 @@
+
+
+
+ QuickAdapterDemo
+ Hello world!
+ Settings
+ Single Layout
+ Muti Layout
+ Picasso Image
+
+
diff --git a/quick-adapter-demo/app/src/main/res/values/styles.xml b/quick-adapter-demo/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/quick-adapter-demo/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/quick-adapter-demo/build.gradle b/quick-adapter-demo/build.gradle
new file mode 100644
index 0000000..6356aab
--- /dev/null
+++ b/quick-adapter-demo/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/quick-adapter-demo/gradle.properties b/quick-adapter-demo/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/quick-adapter-demo/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/quick-adapter-demo/gradle/wrapper/gradle-wrapper.jar b/quick-adapter-demo/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/quick-adapter-demo/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/quick-adapter-demo/gradle/wrapper/gradle-wrapper.properties b/quick-adapter-demo/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/quick-adapter-demo/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/quick-adapter-demo/gradlew b/quick-adapter-demo/gradlew
new file mode 100644
index 0000000..91a7e26
--- /dev/null
+++ b/quick-adapter-demo/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/quick-adapter-demo/gradlew.bat b/quick-adapter-demo/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/quick-adapter-demo/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/quick-adapter-demo/quick-adapter-demo.iml b/quick-adapter-demo/quick-adapter-demo.iml
new file mode 100644
index 0000000..8ffc04a
--- /dev/null
+++ b/quick-adapter-demo/quick-adapter-demo.iml
@@ -0,0 +1,220 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/quick-adapter-demo/settings.gradle b/quick-adapter-demo/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/quick-adapter-demo/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/side-menu-demo/.gitignore b/side-menu-demo/.gitignore
new file mode 100644
index 0000000..0f885ac
--- /dev/null
+++ b/side-menu-demo/.gitignore
@@ -0,0 +1,5 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+.DS_Store
+/build
diff --git a/view-pager-indicator-demo-longtaoge/library/res/values/vpi__styles.xml b/view-pager-indicator-demo-longtaoge/library/res/values/vpi__styles.xml
index 8c4bb84..185e285 100644
--- a/view-pager-indicator-demo-longtaoge/library/res/values/vpi__styles.xml
+++ b/view-pager-indicator-demo-longtaoge/library/res/values/vpi__styles.xml
@@ -12,7 +12,7 @@
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.
+ limitations under the License.
-->