Skip to content

Commit

Permalink
New Example Project
Browse files Browse the repository at this point in the history
  • Loading branch information
davideas committed Jul 20, 2015
1 parent ea7ad8e commit 254ee60
Show file tree
Hide file tree
Showing 44 changed files with 558 additions and 49 deletions.
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# FlexibleAdapter
#### Version of 2015.07.03
#### A pattern for every RecycleView
#### Version of 2015.07.20
#### A pattern for every RecyclerView

The functionalities are taken from different blogs (see at the bottom of the page), merged and methods have been improved for speed and scalability, for all Activities that use a RecycleView.
The functionalities are taken from different Blogs (see at the bottom of the page), merged and methods have been improved for speed and scalability, for all Activities that use a RecycleView.

* At lower class there is SelectableAdapter that provides selection functionalities and it's able to _maintain the state_ after the rotation, you just need to call the onSave/onRestore methods from the Activity!
* Then, the class FlexibleAdapter handles the content paying attention at the animations (calling notify only for the position. _Note:_ you still need to set your animation to the RecyclerView when you create it in the Activity).
Expand All @@ -12,15 +12,15 @@ I've put the click listeners inside the ViewHolder and the Set is done at the cr

Also note that this adapter handles the basic clicks: _single_ and _long clicks_. If you need a double tap you need to implement the android.view.GestureDetector.

**Notes:**
There's an example adapter which does not compile because you need to change the classes with the ones you have in your project :-)

I still have to improve it, so keep an eye on it.
I would like to add some new functionalities, like the Undo (Time is always missing).
I would like to add some new functionalities, like the Undo.

# Screenshots
![Main screen](/screenshots/main_screen.png) ![Multi Selection](/screenshots/multi_selection.png)

#Setup
Ultra simple:
No needs to create and import library for just 2 files, so just *copy* SelectableAdapter.java & FlexibleAdapter.java in your *common* package and start to *extend* FlexibleAdapter from your custom Adapter (see my example Adapter).
No needs to create and import library for just 2 files, so just *copy* SelectableAdapter.java & FlexibleAdapter.java in your *common* package and start to *extend* FlexibleAdapter from your custom Adapter (see my ExampleAdapter).

####Pull requests / Issues / Improvement requests
Feel free to do and ask!
Expand All @@ -42,8 +42,10 @@ In your activity change the Mode for the _ActionMode_ object.
mActionMode = null;
}


#Change Log
**2015.07.20**
- New full working example Android Studio project! (with some nice extra-features)

**2015.07.03**
- Added new method _updateItem()_
- Deprecated _removeSelection()_ -> Use _toggleSelection()_ instead!
Expand All @@ -62,7 +64,6 @@ In your activity change the Mode for the _ActionMode_ object.
- Initial release

#Thanks

I've used these blogs as starting point:

http://enoent.fr/blog/2015/01/18/recyclerview-basics/
Expand Down
4 changes: 2 additions & 2 deletions flexibleAdapter/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ android {
applicationId "eu.davidea.flexibleadapter"
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0"
versionCode 4
versionName "2015.07.20"
}
buildTypes {
release {
Expand Down
2 changes: 1 addition & 1 deletion flexibleAdapter/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name="eu.davidea.example.MainActivity">
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
Expand Down
Binary file modified flexibleAdapter/src/main/ic_launcher-web.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package eu.davidea.flexibleadapter;
package eu.davidea.common;

import java.util.Collections;
import java.util.Comparator;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package eu.davidea.flexibleadapter;
package eu.davidea.common;

import java.util.ArrayList;
import java.util.Iterator;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package eu.davidea.example;
package eu.davidea.common;

import android.content.Context;
import android.content.res.TypedArray;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package eu.davidea.common;

import android.text.Editable;
import android.text.TextWatcher;

/**
* {@link TextWatcher} implementation that does nothing by default
*/
public abstract class SimpleTextWatcher implements TextWatcher {

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {

}

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

@Override
public void afterTextChanged(Editable s) {

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package eu.davidea.flexibleadapter;

import android.annotation.SuppressLint;
import android.app.DialogFragment;
import android.app.Fragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;

import eu.davidea.common.SimpleTextWatcher;
import eu.davidea.utils.Utils;


public class EditItemDialog extends DialogFragment {

public static final String TAG = EditItemDialog.class.getSimpleName();
public static final String ARG_ITEM = "item";
public static final String ARG_ITEM_POSITION = "position";

public interface OnEditItemListener {
void onTitleModified(int position, String newTitle);
}

private Item mItem;
private int mPosition;

public EditItemDialog() {
}

public static EditItemDialog newInstance(Item item, int position) {
return newInstance(item, position, null);
}

public static EditItemDialog newInstance(Item item, int position, Fragment fragment) {
EditItemDialog dialog = new EditItemDialog();
Bundle args = new Bundle();
args.putSerializable(ARG_ITEM, item);
args.putInt(ARG_ITEM_POSITION, position);
dialog.setArguments(args);
dialog.setArguments(args);
dialog.setTargetFragment(fragment, 0);
return dialog;
}

private OnEditItemListener getListener() {
OnEditItemListener listener = (OnEditItemListener) getTargetFragment();
if (listener == null) {
listener = (OnEditItemListener) getActivity();
}
return listener;
}

@Override
public void onSaveInstanceState(Bundle outState) {
outState.putSerializable(ARG_ITEM, mItem);
super.onSaveInstanceState(outState);
}

@Override
public void onStart() {
super.onStart();
getDialog().getWindow().setWindowAnimations(R.style.animation_slide_from_right);
}

@SuppressLint({"InflateParams", "HandlerLeak"})
@Override
public AlertDialog onCreateDialog(Bundle savedInstanceState) {
//Pick up bundle parameters
Bundle bundle;
if (savedInstanceState == null) {
bundle = getArguments();
} else {
bundle = savedInstanceState;
}

mItem = (Item) bundle.getSerializable(ARG_ITEM);
mPosition = bundle.getInt(ARG_ITEM_POSITION);

//Inflate custom view
View dialogView = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_edit_item, null);

final EditText editText = (EditText) dialogView.findViewById(R.id.text_edit_title);

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());//, R.style.AppTheme_AlertDialog);
builder.setTitle(R.string.dialog_edit_title)
.setView(dialogView)
.setNegativeButton(R.string.CANCEL, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Utils.hideSoftInputFrom(getActivity(), editText);
dialog.dismiss();
}
})
.setPositiveButton(R.string.OK, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
getListener().onTitleModified(mPosition,
editText.getText().toString().trim());
Utils.hideSoftInputFrom(getActivity(), editText);
dialog.dismiss();
}
});

final AlertDialog editDialog = builder.create();

editDialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
updateOkButtonState(editDialog, null);
}
});

if (mItem != null) {
editText.setText(mItem.getTitle());
editText.selectAll();
}
editText.requestFocus();
editText.addTextChangedListener(new SimpleTextWatcher() {
private final static long DELAY = 400L;
private final static int TRIGGER = 1;

private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == TRIGGER) {
updateOkButtonState(editDialog, editText);
}
}
};

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
updateOkButtonState(editDialog, null);
}

@Override
public void afterTextChanged(Editable s) {
mHandler.removeMessages(TRIGGER);
mHandler.sendEmptyMessageDelayed(TRIGGER, DELAY);
}
});

editDialog.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);

return editDialog;
}

private void updateOkButtonState(AlertDialog dialog, EditText editText) {
Button buttonOK = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
if (editText == null || (editText.getText().toString().trim()).length() == 0) {
buttonOK.setEnabled(false);
return;
}
if (mItem != null && !mItem.getTitle().equalsIgnoreCase(editText.getText().toString().trim())) {
buttonOK.setEnabled(true);
} else {
editText.setError(getActivity().getString(R.string.err_no_edit));
buttonOK.setEnabled(false);
}

return;
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package eu.davidea.example;
package eu.davidea.flexibleadapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
Expand All @@ -13,8 +13,7 @@
import java.util.ArrayList;
import java.util.List;

import eu.davidea.flexibleadapter.FlexibleAdapter;
import eu.davidea.flexibleadapter.R;
import eu.davidea.common.FlexibleAdapter;


public class ExampleAdapter extends FlexibleAdapter<ExampleAdapter.SimpleViewHolder, Item> {
Expand Down Expand Up @@ -157,13 +156,13 @@ public void run() {
} else {
//Display the current flip status
//setFlipped(holder.mImageView, isSelected(position));
}

//This "if-else" is just an example
if (isSelected(position)) {
holder.mImageView.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.image_round_selected));
} else {
holder.mImageView.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.image_round_normal));
}
//This "if-else" is just an example
if (isSelected(position)) {
holder.mImageView.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.image_round_selected));
} else {
holder.mImageView.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.image_round_normal));
}

holder.mTitle.setText(item.getTitle());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package eu.davidea.example;
package eu.davidea.flexibleadapter;

import java.io.Serializable;

public class Item implements Serializable {

private static final long serialVersionUID = -6882745111884490060L;

public class Item {
private int id;
private String title;
private String subtitle;
Expand Down
Loading

0 comments on commit 254ee60

Please sign in to comment.