{
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/CommonAdapter/src/main/AndroidManifest.xml b/CommonAdapter/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..6657597
--- /dev/null
+++ b/CommonAdapter/src/main/AndroidManifest.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/CommonAdapter/src/main/java/ganke/adapter/BaseAdapterHelper.java b/CommonAdapter/src/main/java/ganke/adapter/BaseAdapterHelper.java
new file mode 100644
index 0000000..f998104
--- /dev/null
+++ b/CommonAdapter/src/main/java/ganke/adapter/BaseAdapterHelper.java
@@ -0,0 +1,487 @@
+/**
+ * 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 ganke.adapter;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Paint;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.text.util.Linkify;
+import android.util.SparseArray;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AlphaAnimation;
+import android.widget.Adapter;
+import android.widget.AdapterView;
+import android.widget.Checkable;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.RatingBar;
+import android.widget.TextView;
+
+/**
+ * Allows an abstraction of the ViewHolder pattern.
+ *
+ *
+ * Usage
+ *
+ *
+ * return BaseAdapterHelper.get(context, convertView, parent, R.layout.item)
+ * .setText(R.id.tvName, contact.getName())
+ * .setText(R.id.tvEmails, contact.getEmails().toString())
+ * .setText(R.id.tvNumbers, contact.getNumbers().toString())
+ * .getView();
+ *
+ */
+public class BaseAdapterHelper {
+
+ /** Views indexed with their IDs */
+ private final SparseArray views;
+
+ private final Context context;
+
+ protected int position;
+
+ private View convertView;
+
+ /** Package private field to retain the associated user object and detect a change */
+ Object associatedObject;
+
+ protected 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;
+ }
+
+ /**
+ * 异步下载图片,需自行实现
+ * @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;
+ }
+
+ /** 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 listview or gridview's item click listener of the view
+ * @param viewId The view id.
+ * @param listener The item on click listener;
+ * @return The BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setOnItemClickListener(int viewId,AdapterView.OnItemClickListener listener) {
+ AdapterView view = retrieveView(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 BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setOnItemLongClickListener(int viewId,AdapterView.OnItemLongClickListener listener) {
+ AdapterView view = retrieveView(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 BaseAdapterHelper for chaining.
+ */
+ public BaseAdapterHelper setOnItemSelectedClickListener(int viewId,AdapterView.OnItemSelectedListener listener) {
+ AdapterView view = retrieveView(viewId);
+ view.setOnItemSelectedListener(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 datas 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")
+ protected 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/CommonAdapter/src/main/java/ganke/adapter/BaseQuickAdapter.java b/CommonAdapter/src/main/java/ganke/adapter/BaseQuickAdapter.java
new file mode 100644
index 0000000..5b871ec
--- /dev/null
+++ b/CommonAdapter/src/main/java/ganke/adapter/BaseQuickAdapter.java
@@ -0,0 +1,163 @@
+/**
+ * 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 ganke.adapter;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+
+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 datas;
+
+ /**
+ * 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 datas.
+ * @param context The context.
+ * @param layoutResId The layout resource id of each item.
+ * @param datas A new list is created out of this one to avoid mutable list
+ */
+ public BaseQuickAdapter(Context context, int layoutResId, List datas) {
+ this.datas = datas == null ? new ArrayList() : new ArrayList(datas);
+ this.context = context;
+ this.layoutResId = layoutResId;
+ }
+
+ @Override
+ public int getCount() {
+ return datas.size();
+ }
+
+ @Override
+ public T getItem(int position) {
+ if (position >= datas.size()) return null;
+ return datas.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final H helper = getAdapterHelper(position, convertView, parent);
+ T item = getItem(position);
+ convert(helper, item, position);
+ helper.setAssociatedObject(item);
+ return helper.getView();
+ }
+
+
+ @Override
+ public boolean isEnabled(int position) {
+ return position < datas.size();
+ }
+
+ public void add(T elem) {
+ datas.add(elem);
+ notifyDataSetChanged();
+ }
+
+ public void addAll(List elem) {
+ datas.addAll(elem);
+ notifyDataSetChanged();
+ }
+
+ public void set(T oldElem, T newElem) {
+ set(datas.indexOf(oldElem), newElem);
+ }
+
+ public void set(int index, T elem) {
+ datas.set(index, elem);
+ notifyDataSetChanged();
+ }
+
+ public void remove(T elem) {
+ datas.remove(elem);
+ notifyDataSetChanged();
+ }
+
+ public void remove(int index) {
+ datas.remove(index);
+ notifyDataSetChanged();
+ }
+
+ public void replaceAll(List elem) {
+ datas.clear();
+ datas.addAll(elem);
+ notifyDataSetChanged();
+ }
+
+ public boolean contains(T elem) {
+ return datas.contains(elem);
+ }
+
+ /** Clear datas list */
+ public void clear() {
+ datas.clear();
+ 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, int position);
+
+ /**
+ * 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 datas 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 datas, 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/CommonAdapter/src/main/java/ganke/adapter/EnhancedQuickAdapter.java b/CommonAdapter/src/main/java/ganke/adapter/EnhancedQuickAdapter.java
new file mode 100644
index 0000000..585ebdb
--- /dev/null
+++ b/CommonAdapter/src/main/java/ganke/adapter/EnhancedQuickAdapter.java
@@ -0,0 +1,56 @@
+/**
+ * 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 ganke.adapter;
+
+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 {
+
+ public EnhancedQuickAdapter(Context context, int layoutResId) {
+ super(context, layoutResId);
+ }
+
+ public EnhancedQuickAdapter(Context context, int layoutResId, List datas) {
+ super(context, layoutResId, datas);
+ }
+
+ @Override
+ protected final void convert(BaseAdapterHelper helper, T item, int position) {
+ boolean itemChanged = helper.associatedObject == null || !helper.associatedObject.equals(item);
+ helper.associatedObject = item;
+ convert(helper, item, position, 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, int position, boolean itemChanged);
+}
diff --git a/CommonAdapter/src/main/java/ganke/adapter/QuickAdapter.java b/CommonAdapter/src/main/java/ganke/adapter/QuickAdapter.java
new file mode 100644
index 0000000..c1bccfe
--- /dev/null
+++ b/CommonAdapter/src/main/java/ganke/adapter/QuickAdapter.java
@@ -0,0 +1,45 @@
+/**
+ * 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 ganke.adapter;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+
+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 QuickAdapter extends BaseQuickAdapter {
+
+ public QuickAdapter(Context context, int layoutResId) {
+ super(context, layoutResId);
+ }
+
+ public QuickAdapter(Context context, int layoutResId, List datas) {
+ super(context, layoutResId, datas);
+ }
+
+ protected BaseAdapterHelper getAdapterHelper(int position, View convertView, ViewGroup parent) {
+ return BaseAdapterHelper.get(context, convertView, parent, layoutResId, position);
+ }
+
+}
diff --git a/CommonAdapter/src/main/res/values/strings.xml b/CommonAdapter/src/main/res/values/strings.xml
new file mode 100644
index 0000000..6d51856
--- /dev/null
+++ b/CommonAdapter/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Library
+
diff --git a/app/build.gradle b/app/build.gradle
index 62aabd7..084f9cb 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -35,4 +35,5 @@ dependencies {
compile 'com.jakewharton:butterknife:7.0.1'
compile 'com.mcxiaoke.volley:library:1.0.18'
compile 'com.github.kassadin:PullToRefresh:1.0.2'
+ compile project(':CommonAdapter')
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 95ddb9e..7d979c9 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,6 +2,8 @@
+
+
kassadin@foxmail.com on 15/8/21 21:38
*/
public class GankeApp extends Application {
- private static GankeApp INSTANCE;
-
- public static GankeApp getInstance() {
- return INSTANCE;
- }
+ private static RequestQueue requestQueue;
@Override
public void onCreate() {
super.onCreate();
- INSTANCE = this;
+ requestQueue = Volley.newRequestQueue(this);
}
+
+ public static RequestQueue getRequestQueue() {
+ return requestQueue;
+ }
+
}
diff --git a/app/src/main/java/com/github/koooe/ganke/api/Api.java b/app/src/main/java/com/github/koooe/ganke/api/Api.java
index 69135d4..19e51d7 100644
--- a/app/src/main/java/com/github/koooe/ganke/api/Api.java
+++ b/app/src/main/java/com/github/koooe/ganke/api/Api.java
@@ -1,14 +1,40 @@
package com.github.koooe.ganke.api;
+import com.android.volley.Response;
+import com.android.volley.toolbox.StringRequest;
+import com.github.koooe.ganke.GankeApp;
+import com.github.koooe.ganke.util.DebugLog;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
/**
* Created by kassadin@foxmail.com on 15/8/21 22:32
*/
public class Api {
- public static final String[] categories = {"iOS",
- "Android",
- "瞎推荐",
- "拓展资源",
- "福利",
- "休息视频"};
+ public static final String[] categories = {"Android", "iOS",
+ "前端", "拓展资源","福利", "休息视频"};
+
+ public static final int PAGE_ZISE = 10;
+ public static final String GANK_DATA = "http://gank.avosapps.com/api/data/%s/" + PAGE_ZISE + "/%d";
+ public static final String GANK_DAY = "http://gank.avosapps.com/api/day/2015/08/06";
+ public static final String GANK_RAMDOM = "http://gank.avosapps.com/api/random/data/Android/20";
+
+
+ public static void getData(String category, int page, Response.Listener listener,
+ Response.ErrorListener errorListener){
+ try {
+ category = URLEncoder.encode(category, "utf-8");
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+
+ String url = String.format(GANK_DATA, category, page);
+ DebugLog.d(url);
+ StringRequest request = new StringRequest(url, listener, errorListener);
+ GankeApp.getRequestQueue().add(request);
+
+ }
+
}
diff --git a/app/src/main/java/com/github/koooe/ganke/bean/BaseResponse.java b/app/src/main/java/com/github/koooe/ganke/bean/BaseResponse.java
new file mode 100644
index 0000000..703aff3
--- /dev/null
+++ b/app/src/main/java/com/github/koooe/ganke/bean/BaseResponse.java
@@ -0,0 +1,25 @@
+package com.github.koooe.ganke.bean;
+
+import java.util.List;
+
+public class BaseResponse {
+
+ private boolean error;
+ private List results;
+
+ public boolean isError() {
+ return error;
+ }
+
+ public void setError(boolean error) {
+ this.error = error;
+ }
+
+ public List getResults() {
+ return results;
+ }
+
+ public void setResults(List results) {
+ this.results = results;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/github/koooe/ganke/bean/DayData.java b/app/src/main/java/com/github/koooe/ganke/bean/DayData.java
new file mode 100644
index 0000000..2bc9c6e
--- /dev/null
+++ b/app/src/main/java/com/github/koooe/ganke/bean/DayData.java
@@ -0,0 +1,94 @@
+package com.github.koooe.ganke.bean;
+
+public class DayData {
+ private String who;
+
+ private String publishedAt;
+
+ private String desc;
+
+ private String type;
+
+ private String url;
+
+ private boolean used;
+
+ private String objectId;
+
+ private String createdAt;
+
+ private String updatedAt;
+
+ public String getWho() {
+ return this.who;
+ }
+
+ public void setWho(String who) {
+ this.who = who;
+ }
+
+ public String getPublishedAt() {
+ return this.publishedAt;
+ }
+
+ public void setPublishedAt(String publishedAt) {
+ this.publishedAt = publishedAt;
+ }
+
+ public String getDesc() {
+ return this.desc;
+ }
+
+ public void setDesc(String desc) {
+ this.desc = desc;
+ }
+
+ public String getType() {
+ return this.type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getUrl() {
+ return this.url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public boolean getUsed() {
+ return this.used;
+ }
+
+ public void setUsed(boolean used) {
+ this.used = used;
+ }
+
+ public String getObjectId() {
+ return this.objectId;
+ }
+
+ public void setObjectId(String objectId) {
+ this.objectId = objectId;
+ }
+
+ public String getCreatedAt() {
+ return this.createdAt;
+ }
+
+ public void setCreatedAt(String createdAt) {
+ this.createdAt = createdAt;
+ }
+
+ public String getUpdatedAt() {
+ return this.updatedAt;
+ }
+
+ public void setUpdatedAt(String updatedAt) {
+ this.updatedAt = updatedAt;
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/github/koooe/ganke/ui/BaseFragment.java b/app/src/main/java/com/github/koooe/ganke/ui/BaseFragment.java
index e5a02a7..b5a98b0 100644
--- a/app/src/main/java/com/github/koooe/ganke/ui/BaseFragment.java
+++ b/app/src/main/java/com/github/koooe/ganke/ui/BaseFragment.java
@@ -6,22 +6,39 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.Toast;
+import com.android.volley.Response;
+import com.android.volley.VolleyError;
import com.github.koooe.ganke.R;
+import com.github.koooe.ganke.api.Api;
+import com.github.koooe.ganke.bean.BaseResponse;
+import com.github.koooe.ganke.bean.DayData;
+import com.github.koooe.ganke.util.DebugLog;
+import com.google.gson.Gson;
import com.markmao.pulltorefresh.widget.XListView;
+import java.util.ArrayList;
+import java.util.List;
+
import butterknife.Bind;
import butterknife.ButterKnife;
+import ganke.adapter.BaseAdapterHelper;
+import ganke.adapter.QuickAdapter;
-
-public class BaseFragment extends Fragment {
+public class BaseFragment extends Fragment implements XListView.IXListViewListener {
private static final String ARG_CATEGORY = "category";
-
- private String category;
-
+ public QuickAdapter adapter;
+ int currentPage;
@Bind(R.id.list_view)
XListView mListView;
+ private String category;
+ private List dayDatas = new ArrayList<>();
+
+ public BaseFragment() {
+ // Required empty public constructor
+ }
public static BaseFragment newInstance(String category) {
BaseFragment fragment = new BaseFragment();
@@ -31,10 +48,6 @@ public static BaseFragment newInstance(String category) {
return fragment;
}
- public BaseFragment() {
- // Required empty public constructor
- }
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -56,20 +69,67 @@ public void onViewCreated(View view, Bundle savedInstanceState) {
mListView.setPullLoadEnable(true);
mListView.setPullRefreshEnable(true);
mListView.setAutoLoadEnable(true);
- mListView.setXListViewListener(new XListView.IXListViewListener() {
+ mListView.setXListViewListener(this);
+ mListView.autoRefresh();
+ adapter = new QuickAdapter(getActivity(), R.layout.listitem_base, dayDatas) {
@Override
- public void onRefresh() {
-
+ protected void convert(BaseAdapterHelper helper, DayData item, int position) {
+ String meta = "Via" + item.getWho() + " @ " + item.getPublishedAt();
+ helper.setText(R.id.tv_desc, item.getDesc());
+ helper.setText(R.id.tv_meta, meta);
}
+ };
+ mListView.setAdapter(adapter);
- @Override
- public void onLoadMore() {
+ }
- }
- });
- mListView.autoRefresh();
- }
+ @Override
+ public void onRefresh() {
+ currentPage = 1;
+ Api.getData(category, currentPage,
+ new Response.Listener() {
+ @Override
+ public void onResponse(String response) {
+ Gson gson = new Gson();
+ BaseResponse baseResponse = gson.fromJson(response, BaseResponse.class);
+ if (!baseResponse.isError()) {
+ adapter.replaceAll(baseResponse.getResults());
+ }
+
+ mListView.stopRefresh();
+ }
+
+ }, new Response.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ DebugLog.e(error.toString());
+ Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+ @Override
+ public void onLoadMore() {
+ Api.getData(category, ++currentPage,
+ new Response.Listener() {
+ @Override
+ public void onResponse(String response) {
+ Gson gson = new Gson();
+ BaseResponse baseResponse = gson.fromJson(response, BaseResponse.class);
+ if (!baseResponse.isError()) {
+ adapter.addAll(baseResponse.getResults());
+ }
+
+ mListView.stopLoadMore();
+ }
+
+ }, new Response.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ Toast.makeText(getActivity(), error.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
}
diff --git a/app/src/main/java/com/github/koooe/ganke/ui/MainActivity.java b/app/src/main/java/com/github/koooe/ganke/ui/MainActivity.java
index fdf7e3a..a5e1a18 100644
--- a/app/src/main/java/com/github/koooe/ganke/ui/MainActivity.java
+++ b/app/src/main/java/com/github/koooe/ganke/ui/MainActivity.java
@@ -4,7 +4,7 @@
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentPagerAdapter;
+import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import com.github.koooe.ganke.R;
@@ -19,7 +19,7 @@ public class MainActivity extends ToolbarActivity {
TabLayout tabLayout;
@Bind(R.id.viewPager)
- private ViewPager viewPager;
+ ViewPager viewPager;
FragmentManager fm;
private MainFragmentPagerAdapter mainAdapter;
@@ -41,7 +41,7 @@ private void init() {
fm = getSupportFragmentManager();
for (int i = 0; i < Api.categories.length; i++) {
- tabLayout.addTab(tabLayout.newTab().setText(Api.categories[i] + i));
+ tabLayout.addTab(tabLayout.newTab().setText(Api.categories[i]));
}
mainAdapter = new MainFragmentPagerAdapter(fm, Api.categories.length);
@@ -52,7 +52,7 @@ private void init() {
}
- static class MainFragmentPagerAdapter extends FragmentPagerAdapter {
+ static class MainFragmentPagerAdapter extends FragmentStatePagerAdapter {
int size;
diff --git a/app/src/main/java/com/github/koooe/ganke/util/DebugLog.java b/app/src/main/java/com/github/koooe/ganke/util/DebugLog.java
new file mode 100644
index 0000000..e20334d
--- /dev/null
+++ b/app/src/main/java/com/github/koooe/ganke/util/DebugLog.java
@@ -0,0 +1,109 @@
+
+/***
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+For more information, please refer to
+*/
+
+package com.github.koooe.ganke.util;
+
+import android.util.Log;
+
+import com.github.koooe.ganke.BuildConfig;
+
+
+/**
+ * @date 21.06.2012
+ * @author Mustafa Ferhan Akman
+ *
+ * Create a simple and more understandable Android logs.
+ * */
+
+public class DebugLog{
+
+ static String className;
+ static String methodName;
+ static int lineNumber;
+
+ private DebugLog(){
+ /* Protect from instantiations */
+ }
+
+ public static boolean isDebuggable() {
+ return BuildConfig.DEBUG;
+ }
+
+ private static String createLog( String log ) {
+
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("[");
+ buffer.append(methodName);
+ buffer.append(":");
+ buffer.append(lineNumber);
+ buffer.append("]");
+ buffer.append(log);
+
+ return buffer.toString();
+ }
+
+ private static void getMethodNames(StackTraceElement[] sElements){
+ className = sElements[1].getFileName();
+ methodName = sElements[1].getMethodName();
+ lineNumber = sElements[1].getLineNumber();
+ }
+
+ public static void e(String message){
+ if (!isDebuggable())
+ return;
+
+ // Throwable instance must be created before any methods
+ getMethodNames(new Throwable().getStackTrace());
+ Log.e(className, createLog(message));
+ }
+
+ public static void i(String message){
+ if (!isDebuggable())
+ return;
+
+ getMethodNames(new Throwable().getStackTrace());
+ Log.i(className, createLog(message));
+ }
+
+ public static void d(String message){
+ if (!isDebuggable())
+ return;
+
+ getMethodNames(new Throwable().getStackTrace());
+ Log.d(className, createLog(message));
+ }
+
+ public static void v(String message){
+ if (!isDebuggable())
+ return;
+
+ getMethodNames(new Throwable().getStackTrace());
+ Log.v(className, createLog(message));
+ }
+
+ public static void w(String message){
+ if (!isDebuggable())
+ return;
+
+ getMethodNames(new Throwable().getStackTrace());
+ Log.w(className, createLog(message));
+ }
+
+ public static void wtf(String message){
+ if (!isDebuggable())
+ return;
+
+ getMethodNames(new Throwable().getStackTrace());
+ Log.wtf(className, createLog(message));
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 7641cc5..615f717 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -15,9 +15,12 @@
android:background="@color/primary"
android:layout_height="48dp" />
-
+ android:layout_height="match_parent"
+
+ />
+
diff --git a/app/src/main/res/layout/listitem_base.xml b/app/src/main/res/layout/listitem_base.xml
new file mode 100644
index 0000000..f4399ad
--- /dev/null
+++ b/app/src/main/res/layout/listitem_base.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/view_toolbar.xml b/app/src/main/res/layout/view_toolbar.xml
index 0e4ae82..1a82420 100644
--- a/app/src/main/res/layout/view_toolbar.xml
+++ b/app/src/main/res/layout/view_toolbar.xml
@@ -10,7 +10,7 @@
@@ -20,6 +20,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
+ android:gravity="center"
android:textSize="20sp"
android:textColor="@color/black"
android:textStyle="bold"
diff --git a/settings.gradle b/settings.gradle
index e7b4def..9dde99a 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1 @@
-include ':app'
+include ':app', ':CommonAdapter'