mirror of
https://github.com/leanote/leanote-android.git
synced 2026-01-20 07:01:09 +08:00
Merge pull request #15 from leanote/feature/edit-notebook-title
Feature/edit notebook title
This commit is contained in:
@@ -104,4 +104,6 @@ dependencies {
|
||||
compile 'com.elvishew:xlog:1.3.0'
|
||||
compile 'com.github.piasy:BigImageViewer:1.2.5'
|
||||
compile 'com.github.piasy:GlideImageLoader:1.2.5'
|
||||
compile 'com.weiwangcn.betterspinner:library-material:1.1.0'
|
||||
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.houxg.leamonax.database.AppDataBase;
|
||||
import org.houxg.leamonax.model.Notebook;
|
||||
import org.houxg.leamonax.service.AccountService;
|
||||
import org.houxg.leamonax.utils.CollectionUtils;
|
||||
import org.houxg.leamonax.utils.ToastUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -100,7 +101,7 @@ public class NotebookAdapter extends RecyclerView.Adapter<NotebookAdapter.Notebo
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mListener != null) {
|
||||
mListener.onClickedAddNotebook(getCurrentParentId());
|
||||
mListener.onClickedAddNotebook(getCurrentParentId(), mData);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -113,14 +114,16 @@ public class NotebookAdapter extends RecyclerView.Adapter<NotebookAdapter.Notebo
|
||||
String notebookId = notebook.getNotebookId();
|
||||
boolean isSuper = isSuper(notebookId);
|
||||
boolean isSuperOrRoot = isSuper | mStack.isEmpty();
|
||||
boolean hasChild = hasChild(notebookId);
|
||||
final boolean hasChild = hasChild(notebookId);
|
||||
holder.placeholder.setVisibility(isSuperOrRoot ? View.GONE : View.VISIBLE);
|
||||
holder.navigator.setVisibility(mCanOpenEmpty | hasChild ? View.VISIBLE : View.INVISIBLE);
|
||||
holder.navigator.setImageResource(isSuper ? R.drawable.ic_expanding : R.drawable.ic_expandable);
|
||||
holder.navigator.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
//TODO: arrow animation
|
||||
if (!hasChild) {
|
||||
return;
|
||||
}
|
||||
if (isSuper(notebook.getNotebookId())) {
|
||||
listUpper();
|
||||
} else {
|
||||
@@ -132,11 +135,19 @@ public class NotebookAdapter extends RecyclerView.Adapter<NotebookAdapter.Notebo
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mListener != null) {
|
||||
listChild(notebook);
|
||||
mListener.onClickedNotebook(notebook);
|
||||
}
|
||||
}
|
||||
});
|
||||
holder.titleTv.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
if (mListener != null) {
|
||||
mListener.onEditNotebook(notebook);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isSuper(String notebookId) {
|
||||
@@ -196,7 +207,9 @@ public class NotebookAdapter extends RecyclerView.Adapter<NotebookAdapter.Notebo
|
||||
public interface NotebookAdapterListener {
|
||||
void onClickedNotebook(Notebook notebook);
|
||||
|
||||
void onClickedAddNotebook(String parentNotebookId);
|
||||
void onClickedAddNotebook(String parentNotebookId, List<Notebook> notebooks);
|
||||
|
||||
void onEditNotebook(Notebook notebook);
|
||||
}
|
||||
|
||||
static class NotebookHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
@@ -19,4 +19,9 @@ public interface NotebookApi {
|
||||
|
||||
@POST("notebook/addNotebook")
|
||||
Call<Notebook> addNotebook(@Query("title") String title, @Query("parentNotebookId") String parentId);
|
||||
|
||||
@POST("notebook/updateNotebook")
|
||||
Call<Notebook> updateNotebook(@Query("notebookId") String notebookId, @Query("title") String title,
|
||||
@Query("parentNotebookId") String parentId, @Query("seq") int seq, @Query("usn") int usn);
|
||||
|
||||
}
|
||||
|
||||
@@ -36,4 +36,24 @@ public class NotebookService {
|
||||
Notebook notebook = AppDataBase.getNotebookByLocalId(notebookLocalId);
|
||||
return notebook != null ? notebook.getTitle() : "";
|
||||
}
|
||||
|
||||
public static Notebook updateNotebook(String title, Notebook notebook) {
|
||||
Notebook newNotebook = RetrofitUtils.excute(ApiProvider.getInstance().getNotebookApi().
|
||||
updateNotebook(notebook.getNotebookId(), title, notebook.getParentNotebookId(), notebook.getSeq(), notebook.getUsn()));
|
||||
if (newNotebook == null) {
|
||||
throw new IllegalStateException("Network error");
|
||||
}
|
||||
if (newNotebook.isOk()) {
|
||||
Account account = AccountService.getCurrent();
|
||||
if (notebook.getUsn() - account.getNotebookUsn() == 1) {
|
||||
account.setNotebookUsn(notebook.getUsn());
|
||||
account.save();
|
||||
}
|
||||
newNotebook.setId(notebook.getId());
|
||||
newNotebook.update();
|
||||
return notebook;
|
||||
} else {
|
||||
throw new IllegalStateException(notebook.getMsg());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,18 +6,13 @@ import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.RippleDrawable;
|
||||
import android.os.Build;
|
||||
import android.support.v4.view.GravityCompat;
|
||||
import android.support.v4.view.ViewGroupCompat;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.graphics.drawable.DrawableWrapper;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -27,9 +22,8 @@ import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.elvishew.xlog.XLog;
|
||||
import com.tencent.bugly.Bugly;
|
||||
import com.tencent.bugly.crashreport.CrashReport;
|
||||
import com.weiwangcn.betterspinner.library.material.MaterialBetterSpinner;
|
||||
|
||||
import org.houxg.leamonax.R;
|
||||
import org.houxg.leamonax.adapter.AccountAdapter;
|
||||
@@ -41,10 +35,17 @@ import org.houxg.leamonax.model.Tag;
|
||||
import org.houxg.leamonax.model.User;
|
||||
import org.houxg.leamonax.service.AccountService;
|
||||
import org.houxg.leamonax.service.NotebookService;
|
||||
import org.houxg.leamonax.utils.CollectionUtils;
|
||||
import org.houxg.leamonax.utils.DisplayUtils;
|
||||
import org.houxg.leamonax.utils.OpenUtils;
|
||||
import org.houxg.leamonax.utils.ToastUtils;
|
||||
import org.houxg.leamonax.widget.AlphabetDrawable;
|
||||
import org.houxg.leamonax.widget.TriangleView;
|
||||
import org.houxg.leamonax.widget.spinner.SpinnerArrayAdapter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
@@ -297,9 +298,24 @@ public class Navigation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickedAddNotebook(final String parentNotebookId) {
|
||||
View view = LayoutInflater.from(mActivity).inflate(R.layout.dialog_sigle_edittext, null);
|
||||
public void onClickedAddNotebook(final String parentNotebookId, List<Notebook> notebooks) {
|
||||
View view = LayoutInflater.from(mActivity).inflate(R.layout.dialog_add_notebook, null);
|
||||
final EditText mEdit = (EditText) view.findViewById(R.id.edit);
|
||||
final MaterialBetterSpinner spinner = (MaterialBetterSpinner) view.findViewById(R.id.spinner);
|
||||
final List<Notebook> tempNotebooks = new ArrayList<>();
|
||||
tempNotebooks.clear();
|
||||
tempNotebooks.addAll(notebooks);
|
||||
Notebook rootNoteBook = new Notebook();
|
||||
rootNoteBook.setTitle(mActivity.getString(R.string.notebook_default_root_notebook_title));
|
||||
tempNotebooks.add(0, rootNoteBook);
|
||||
SpinnerArrayAdapter<Notebook> adapter = new SpinnerArrayAdapter<Notebook>(view.getContext(), tempNotebooks) {
|
||||
@Override
|
||||
public String itemToString(Notebook item) {
|
||||
return item.getTitle();
|
||||
}
|
||||
};
|
||||
spinner.setAdapter(adapter);
|
||||
spinner.setText(rootNoteBook.getTitle());
|
||||
new AlertDialog.Builder(mActivity)
|
||||
.setTitle(R.string.add_notebook)
|
||||
.setView(view)
|
||||
@@ -307,7 +323,35 @@ public class Navigation {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
addNotebook(mEdit.getText().toString(), parentNotebookId);
|
||||
addNotebook(mEdit.getText().toString(), getNotebookId(tempNotebooks, spinner.getText().toString()));
|
||||
}
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
private String getNotebookId(List<Notebook> notebooks, String title) {
|
||||
for (Notebook notebook : notebooks) {
|
||||
if (TextUtils.equals(notebook.getTitle(), title)) {
|
||||
return notebook.getNotebookId();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEditNotebook(final Notebook notebook) {
|
||||
View view = LayoutInflater.from(mActivity).inflate(R.layout.dialog_sigle_edittext, null);
|
||||
final EditText mEdit = (EditText) view.findViewById(R.id.edit);
|
||||
mEdit.setText(notebook.getTitle());
|
||||
mEdit.setSelection(notebook.getTitle().length());
|
||||
new AlertDialog.Builder(mActivity)
|
||||
.setTitle(R.string.update_notebook_title)
|
||||
.setView(view)
|
||||
.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
updateNotebook(mEdit.getText().toString(), notebook);
|
||||
}
|
||||
})
|
||||
.show();
|
||||
@@ -323,7 +367,47 @@ public class Navigation {
|
||||
});
|
||||
}
|
||||
|
||||
private void updateNotebook(final String title, final Notebook notebook) {
|
||||
if (TextUtils.isEmpty(title)) {
|
||||
ToastUtils.show(mActivity, R.string.toast_notebook_title_not_empty);
|
||||
return;
|
||||
}
|
||||
Observable.create(
|
||||
new Observable.OnSubscribe<Notebook>() {
|
||||
@Override
|
||||
public void call(Subscriber<? super Notebook> subscriber) {
|
||||
if (!subscriber.isUnsubscribed()) {
|
||||
subscriber.onNext(NotebookService.updateNotebook(title, notebook));
|
||||
subscriber.onCompleted();
|
||||
}
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<Notebook>() {
|
||||
@Override
|
||||
public void onCompleted() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(Notebook isSucceed) {
|
||||
mNotebookAdapter.refresh();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void addNotebook(final String title, final String parentNotebookId) {
|
||||
if (TextUtils.isEmpty(title)) {
|
||||
ToastUtils.show(mActivity, R.string.toast_notebook_title_not_empty);
|
||||
return;
|
||||
}
|
||||
Observable.create(
|
||||
new Observable.OnSubscribe<Notebook>() {
|
||||
@Override
|
||||
|
||||
@@ -15,6 +15,8 @@ import org.houxg.leamonax.R;
|
||||
import org.houxg.leamonax.adapter.NotebookAdapter;
|
||||
import org.houxg.leamonax.model.Notebook;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DialogUtils {
|
||||
|
||||
public static void editLink(Context context, String title, String link, @NonNull final ChangedListener listener) {
|
||||
@@ -72,7 +74,12 @@ public class DialogUtils {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickedAddNotebook(String parentNotebookId) {
|
||||
public void onClickedAddNotebook(String parentNotebookId, List<Notebook> notebooks) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEditNotebook(Notebook notebook) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
package org.houxg.leamonax.widget.spinner;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Filter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class SpinnerArrayAdapter<T> extends ArrayAdapter<SpinnerArrayAdapter<T>.ItemProxy> {
|
||||
|
||||
private NoFilter noFilter;
|
||||
|
||||
public SpinnerArrayAdapter(Context context) {
|
||||
this(context, new ArrayList<T>());
|
||||
}
|
||||
|
||||
public SpinnerArrayAdapter(Context context, List<T> objects) {
|
||||
super(context, android.R.layout.simple_spinner_dropdown_item);
|
||||
setNotifyOnChange(false);
|
||||
addAll(objects);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public SpinnerArrayAdapter(Context context, T[] objects) {
|
||||
this(context, Arrays.asList(objects));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>For default, the ArrayAdapter uses <code>toString()</code> for item view, in somes cases when uses a framework like Realm Database, is not possible to overrides the <code>toString()</code> in model classes.
|
||||
* Then, the proxy solutions has implemented.
|
||||
* <p>This method encapsulates the original object into a proxy.</p>
|
||||
*
|
||||
* @param objects
|
||||
* @return
|
||||
*/
|
||||
private List<ItemProxy> wrapItems(List<T> objects) {
|
||||
List<ItemProxy> proxies = new ArrayList<>(objects.size());
|
||||
for (T item : objects) {
|
||||
ItemProxy proxy = new ItemProxy(item);
|
||||
proxies.add(proxy);
|
||||
}
|
||||
return proxies;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Converts the item to <code>String</code>.</p>
|
||||
* <p>Overrides this method for cutomize the text view.</p>
|
||||
*
|
||||
* @param item
|
||||
* @return
|
||||
*/
|
||||
public String itemToString(T item) {
|
||||
return item.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Converts a <code>String</code> in object.</p>
|
||||
* <p>This method can be used to get selected item.</p>
|
||||
* <p>Example:</p>
|
||||
* <code>
|
||||
* <pre>
|
||||
*
|
||||
* MaterialBetterSpinner spPeople;
|
||||
* SpinnerArrayAdapter<People> adapterPeople;
|
||||
* ....
|
||||
* People pSelected = adapterPeople.stringToItem(spPeople.getText())
|
||||
*
|
||||
* </pre>
|
||||
* </code>
|
||||
*
|
||||
* @param toString Selected text.
|
||||
* @return Object converted from selected text.
|
||||
*/
|
||||
public T stringToItem(String toString) {
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
T item = getItem(i).object;
|
||||
if (itemToString(item).equals(toString)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Converts a <code>String</code> in object.</p>
|
||||
* <p>This method can be used to get selected item.</p>
|
||||
* <p>Example:</p>
|
||||
* <code>
|
||||
* <pre>
|
||||
*
|
||||
* MaterialBetterSpinner spPeople;
|
||||
* SpinnerArrayAdapter<People> adapterPeople;
|
||||
* ....
|
||||
* People pSelected = adapterPeople.stringToItem(spPeople.getText())
|
||||
*
|
||||
* </pre>
|
||||
* </code>
|
||||
*
|
||||
* @param toString Selected text.
|
||||
* @return Object converted from selected text.
|
||||
*/
|
||||
public T stringToItem(CharSequence toString) {
|
||||
return stringToItem(toString.toString());
|
||||
}
|
||||
|
||||
public void addAll(List<T> objects) {
|
||||
clear();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
addAll(wrapItems(objects));
|
||||
} else {
|
||||
for (ItemProxy p : wrapItems(objects)) {
|
||||
add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy for generic SpinnerArrayAdapter.
|
||||
*/
|
||||
public class ItemProxy {
|
||||
public final T object;
|
||||
|
||||
protected ItemProxy(T object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return itemToString(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof SpinnerArrayAdapter.ItemProxy)) return false;
|
||||
|
||||
ItemProxy itemProxy = (ItemProxy) o;
|
||||
|
||||
return !(object != null ? !object.equals(itemProxy.object) : itemProxy.object != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return object != null ? object.hashCode() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override ArrayAdapter.getFilter() to return our own filtering.
|
||||
*/
|
||||
@Override
|
||||
public Filter getFilter() {
|
||||
if (noFilter == null) {
|
||||
noFilter = new NoFilter();
|
||||
}
|
||||
return noFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class which does not perform any filtering.
|
||||
* Filtering is already done by the web service when asking for the list,
|
||||
* so there is no need to do any more as well.
|
||||
* This way, ArrayAdapter.mOriginalValues is not used when calling e.g.
|
||||
* ArrayAdapter.add(), but instead ArrayAdapter.mObjects is updated directly
|
||||
* and methods like getCount() return the expected result.
|
||||
*/
|
||||
private class NoFilter extends Filter {
|
||||
protected FilterResults performFiltering(CharSequence prefix) {
|
||||
return new FilterResults();
|
||||
}
|
||||
|
||||
protected void publishResults(CharSequence constraint,
|
||||
FilterResults results) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
21
app/src/main/res/layout/dialog_add_notebook.xml
Normal file
21
app/src/main/res/layout/dialog_add_notebook.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<com.weiwangcn.betterspinner.library.material.MaterialBetterSpinner
|
||||
android:id="@+id/spinner"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin"
|
||||
android:hint="@string/notebook_choose_notebook_hint" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="8dp" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -108,4 +108,8 @@
|
||||
<string name="host_example">登录接口地址将会是:\n%s/api/login</string>
|
||||
<string name="my_blog">我的博客</string>
|
||||
<string name="explore">蚂蚁笔记探索</string>
|
||||
<string name="toast_notebook_title_not_empty">笔记本的名称不能为空</string>
|
||||
<string name="update_notebook_title">修改笔记本的名称</string>
|
||||
<string name="notebook_choose_notebook_hint">选择该笔记本所在的上一级笔记本目录</string>
|
||||
<string name="notebook_default_root_notebook_title">空目录(最顶层目录)</string>
|
||||
</resources>
|
||||
@@ -110,4 +110,8 @@
|
||||
<string name="host_example">For example, login api will be:\n%s/api/login</string>
|
||||
<string name="my_blog">My Blog</string>
|
||||
<string name="explore">Leanote Explore</string>
|
||||
<string name="toast_notebook_title_not_empty">the notebook title can\'t empty</string>
|
||||
<string name="update_notebook_title">Update notebook title</string>
|
||||
<string name="notebook_choose_notebook_hint">选择该笔记本所在的上一级笔记本目录 Choose current Notebook \'s parentNotebook directory</string>
|
||||
<string name="notebook_default_root_notebook_title">Empty directory</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user