diff --git a/app/build.gradle b/app/build.gradle
index 4f5b8271e8cf52d8c02c376ae4c25ac68094c018..fa3f0b663b795d9ce518b9e8ca955b8b0aa1a72d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -14,16 +14,14 @@ android {
}
signingConfigs {
- release {
- }
}
buildTypes {
- debug {
- signingConfig signingConfigs.release
- }
- release {
- signingConfig signingConfigs.release
- }
+// debug {
+// signingConfig signingConfigs.release
+// }
+// release {
+// signingConfig signingConfigs.release
+// }
}
@@ -34,7 +32,7 @@ android {
}
dependencies {
- compile fileTree(include: ['*.jar'], dir: 'libs')
+ compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':social_sdk_library_project')
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.github.chrisbanes.photoview:library:1.2.3'
@@ -44,6 +42,7 @@ dependencies {
compile 'com.networkbench.newlens.agent.android:nbs.newlens.agent:2.2.5'
compile 'com.google.zxing:core:3.2.0'
compile 'com.joanzapata.android:android-iconify:1.0.9'
+ compile 'se.emilsjolander:stickylistheaders:2.5.2'
}
// 配置签名文件以及相关的账号信息
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 72cd19687ef19ff23acd295323e61fdb5750bc91..fc9fc4fa8356be7efc172b4f6ea64c8b995f5c3e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -171,6 +171,11 @@
android:label="@string/actionbar_title_shake"
android:screenOrientation="portrait"/>
+
+
+
diff --git a/app/src/main/java/net/oschina/app/adapter/FriendsAdapter.java b/app/src/main/java/net/oschina/app/adapter/FriendsAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..e1ea7ee73d4739ccceb3a4dc9685955f1a6172a1
--- /dev/null
+++ b/app/src/main/java/net/oschina/app/adapter/FriendsAdapter.java
@@ -0,0 +1,144 @@
+package net.oschina.app.adapter;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.CheckBox;
+import android.widget.TextView;
+
+import net.oschina.app.R;
+import net.oschina.app.bean.Friend;
+import net.oschina.app.bean.InitialFriend;
+import net.oschina.app.widget.SquareAvatarView;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import butterknife.ButterKnife;
+import butterknife.InjectView;
+
+/**
+ * Description:
+ * User: ZhengXingtian(lan4627@Gmail.com)
+ * Date: 2015-08-28
+ * Time: 03:29
+ * Version: 1.0
+ */
+public class FriendsAdapter extends BaseAdapter {
+
+ public static final int MAXIMUM_CHOOSE = 10;
+
+ protected Context mContext;
+ protected LayoutInflater mInflater;
+ private List mFriends;
+ private Set mCheckedFriends;
+
+ public FriendsAdapter(Context context, List friends){
+ mContext = context;
+ mInflater = LayoutInflater.from(context);
+ mCheckedFriends = new HashSet<>();
+ setDataList(friends);
+ }
+
+ public void setDataList(List friends){
+ mFriends = friends;
+ }
+
+ public void setCheckedFriends(Set checkedFriends){
+ mCheckedFriends = checkedFriends;
+ }
+
+ public Set getCheckedFriends(){
+ return mCheckedFriends;
+ }
+
+ @Override
+ public int getCount() {
+ return mFriends == null ? 0 : mFriends.size();
+ }
+
+ @Override
+ public InitialFriend getItem(int i) {
+ return mFriends.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
+
+ @Override
+ public View getView(int i, View view, ViewGroup viewGroup) {
+ Holder h = null;
+ if (view == null){
+ view = mInflater.inflate(R.layout.item_choose_friend, viewGroup, false);
+ h = new Holder(view);
+ h.mChoose.setOnClickListener(mChooseListener);
+ view.setTag(h);
+ } else {
+ h = (Holder) view.getTag();
+ }
+ Friend friend = mFriends.get(i);
+ h.mName.setText(friend.getName());
+ h.mAvatar.setAvatarUrl(friend.getPortrait());
+ h.mAvatar.setUserInfo(friend.getId(), friend.getName());
+ h.mChoose.setTag(friend);
+ h.mChoose.setTag(R.id.item_position, i);
+ h.mChoose.setChecked(mCheckedFriends.contains(friend.getUserid()));
+ return view;
+ }
+
+ private View.OnClickListener mChooseListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ boolean checked = ((CheckBox)view).isChecked();
+ InitialFriend friend = (InitialFriend) view.getTag();
+ if (checked){
+ // 当是选中状态时,判断是否达到最大个数,是的话要把选中的状态取消掉,防止超过个数
+ if (mCheckedFriends.size() == MAXIMUM_CHOOSE){
+ ((CheckBox)view).setChecked(!checked);
+ return;
+ }
+ mCheckedFriends.add(friend.getUserid());
+ // 通知接口选中的目标变化
+ if (mListener != null){
+ mListener.onAdd(friend, mCheckedFriends.size());
+ }
+ } else {
+ mCheckedFriends.remove(friend.getUserid());
+ if (mListener != null){
+ mListener.onRemove(friend, mCheckedFriends.size());
+ }
+ }
+ }
+ };
+
+ static class Holder{
+ @InjectView(R.id.iv_friend_avatar)
+ SquareAvatarView mAvatar;
+
+ @InjectView(R.id.tv_friend_name)
+ TextView mName;
+
+ @InjectView(R.id.cb_friend_choose)
+ CheckBox mChoose;
+
+ public Holder(View view){
+ ButterKnife.inject(this, view);
+ }
+ }
+
+ private OnChooseChangeListener mListener;
+
+ public void setOnChooseChangeListener(OnChooseChangeListener l){
+ mListener = l;
+ }
+
+ public interface OnChooseChangeListener{
+ void onAdd(InitialFriend friend, int count);
+ void onRemove(InitialFriend friend, int count);
+ }
+}
diff --git a/app/src/main/java/net/oschina/app/adapter/InitialAdapter.java b/app/src/main/java/net/oschina/app/adapter/InitialAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..cec4df28e5e1ffcd6bb7a3f780800bf5b46e17e5
--- /dev/null
+++ b/app/src/main/java/net/oschina/app/adapter/InitialAdapter.java
@@ -0,0 +1,46 @@
+package net.oschina.app.adapter;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import net.oschina.app.R;
+import net.oschina.app.bean.InitialFriend;
+
+import java.util.List;
+
+import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
+
+/**
+ * Description:
+ * User: ZhengXingtian(lan4627@Gmail.com)
+ * Date: 2015-08-28
+ * Time: 03:32
+ * Version: 1.0
+ * 带标题的好友列表适配器
+ */
+public class InitialAdapter extends FriendsAdapter implements StickyListHeadersAdapter {
+
+ public InitialAdapter(Context context, List friends) {
+ super(context, friends);
+ }
+
+ @Override
+ public View getHeaderView(int i, View view, ViewGroup viewGroup) {
+ TextView hv = null;
+ if (view == null){
+ hv = (TextView) mInflater.inflate(R.layout.item_mention_friends_name_head, viewGroup, false);
+ view = hv;
+ } else {
+ hv = (TextView) view;
+ }
+ hv.setText(getItem(i).getInitial());
+ return view;
+ }
+
+ @Override
+ public long getHeaderId(int i) {
+ return getItem(i).getInitial().charAt(0);
+ }
+}
diff --git a/app/src/main/java/net/oschina/app/api/ApiHttpClient.java b/app/src/main/java/net/oschina/app/api/ApiHttpClient.java
index 59613bf921f94f47a8d5f45bcfebb3042234355c..8bf993276e12e46dbeb4c68e933c2ac5a8d6f978 100644
--- a/app/src/main/java/net/oschina/app/api/ApiHttpClient.java
+++ b/app/src/main/java/net/oschina/app/api/ApiHttpClient.java
@@ -16,10 +16,10 @@ import com.loopj.android.http.RequestParams;
public class ApiHttpClient {
-// public final static String HOST = "www.oschina.net";
-// private static String API_URL = "http://www.oschina.net/%s";
- public final static String HOST = "192.168.1.107";
- private static String API_URL = "http://192.168.1.107/%s";
+ public final static String HOST = "www.oschina.net";
+ private static String API_URL = "http://www.oschina.net/%s";
+// public final static String HOST = "192.168.1.107";
+// private static String API_URL = "http://192.168.1.107/%s";
public static final String DELETE = "DELETE";
public static final String GET = "GET";
public static final String POST = "POST";
diff --git a/app/src/main/java/net/oschina/app/api/remote/OSChinaApi.java b/app/src/main/java/net/oschina/app/api/remote/OSChinaApi.java
index a671887902f4deccb74db2bb2a7596a5af72bcf7..b6cea455e1f39def5dd9adebabd9af7cf31e2f6c 100644
--- a/app/src/main/java/net/oschina/app/api/remote/OSChinaApi.java
+++ b/app/src/main/java/net/oschina/app/api/remote/OSChinaApi.java
@@ -644,6 +644,13 @@ public class OSChinaApi {
ApiHttpClient.get("action/api/event_attend_user", params, handler);
}
+ public static void getFriendList(int userId, AsyncHttpResponseHandler handler){
+ RequestParams params = new RequestParams();
+ params.put("uid", userId);
+ params.put("all", 1);
+ ApiHttpClient.get("action/api/friends_list", params, handler);
+ }
+
/**
* 举报
*
diff --git a/app/src/main/java/net/oschina/app/bean/InitialFriend.java b/app/src/main/java/net/oschina/app/bean/InitialFriend.java
new file mode 100644
index 0000000000000000000000000000000000000000..1bf08b66662fe84589bfe44269a2beaa41849676
--- /dev/null
+++ b/app/src/main/java/net/oschina/app/bean/InitialFriend.java
@@ -0,0 +1,39 @@
+package net.oschina.app.bean;
+
+import net.oschina.app.util.FirstLatterUtil;
+
+/**
+ * Description:
+ * User: ZhengXingtian(lan4627@Gmail.com)
+ * Date: 2015-08-28
+ * Time: 03:31
+ * Version: 1.0
+ * 带首字母属性的好友实体类
+ */
+public class InitialFriend extends Friend {
+
+ private String initial;
+
+ public String getInitial() {
+ return initial;
+ }
+
+ public void setInitial(String initial) {
+ this.initial = initial;
+ }
+
+ public static InitialFriend make(Friend f){
+ InitialFriend iFriend = new InitialFriend();
+ iFriend.setInitial(FirstLatterUtil.getFirstLetter(f.getName()).substring(0, 1).toUpperCase());
+ iFriend.setExpertise(f.getExpertise());
+ iFriend.setFrom(f.getFrom());
+ iFriend.setGender(f.getGender());
+ iFriend.setName(f.getName());
+ iFriend.setUserid(f.getUserid());
+ iFriend.setPortrait(f.getPortrait());
+ iFriend.setCacheKey(f.getCacheKey());
+ iFriend.setId(f.getId());
+ iFriend.setNotice(f.getNotice());
+ return iFriend;
+ }
+}
diff --git a/app/src/main/java/net/oschina/app/bean/SimpleBackPage.java b/app/src/main/java/net/oschina/app/bean/SimpleBackPage.java
index 7e40b7f95860bac0148e44ddb1cd0b141f4ac102..0d35c97d5d2b6d831a824de24f998914f0b2602a 100644
--- a/app/src/main/java/net/oschina/app/bean/SimpleBackPage.java
+++ b/app/src/main/java/net/oschina/app/bean/SimpleBackPage.java
@@ -8,6 +8,7 @@ import net.oschina.app.fragment.CommentFrament;
import net.oschina.app.fragment.EventAppliesFragment;
import net.oschina.app.fragment.EventFragment;
import net.oschina.app.fragment.FeedBackFragment;
+import net.oschina.app.fragment.MentionFriendsNameFragment;
import net.oschina.app.fragment.MessageDetailFragment;
import net.oschina.app.fragment.MyInformationFragment;
import net.oschina.app.fragment.MyInformationFragmentDetail;
@@ -139,7 +140,9 @@ public enum SimpleBackPage {
TWEET_LIKE_USER_LIST(41, 0, TweetLikeUsersFragment.class),
- TWEET_TOPIC_LIST(42, 0, TweetsFragment.class);
+ TWEET_TOPIC_LIST(42, 0, TweetsFragment.class),
+
+ MENTION_FRIENDS_NAME(43, R.string.actionbar_title_mention_friends_name, MentionFriendsNameFragment.class);
private int title;
private Class> clz;
diff --git a/app/src/main/java/net/oschina/app/fragment/MentionFriendsNameFragment.java b/app/src/main/java/net/oschina/app/fragment/MentionFriendsNameFragment.java
new file mode 100644
index 0000000000000000000000000000000000000000..be21e46b618be3881efd16c9214733dbbed48839
--- /dev/null
+++ b/app/src/main/java/net/oschina/app/fragment/MentionFriendsNameFragment.java
@@ -0,0 +1,392 @@
+package net.oschina.app.fragment;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.SparseArray;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.loopj.android.http.AsyncHttpResponseHandler;
+
+import net.oschina.app.AppContext;
+import net.oschina.app.R;
+import net.oschina.app.adapter.FriendsAdapter;
+import net.oschina.app.adapter.InitialAdapter;
+import net.oschina.app.api.remote.OSChinaApi;
+import net.oschina.app.base.BaseFragment;
+import net.oschina.app.bean.Friend;
+import net.oschina.app.bean.FriendsList;
+import net.oschina.app.bean.InitialFriend;
+import net.oschina.app.ui.MentionFriendsNameActivity;
+import net.oschina.app.ui.empty.EmptyLayout;
+import net.oschina.app.util.FirstLatterUtil;
+import net.oschina.app.util.TDevice;
+import net.oschina.app.util.UIHelper;
+import net.oschina.app.util.XmlUtils;
+import net.oschina.app.widget.IndexerBar;
+import net.oschina.app.widget.SquareAvatarView;
+import net.oschina.app.widget.tooglebutton.rebound.ui.Util;
+
+import org.apache.http.Header;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import butterknife.ButterKnife;
+import butterknife.InjectView;
+import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
+import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
+
+/**
+ * Description:
+ * User: ZhengXingtian(lan4627@Gmail.com)
+ * Date: 2015-08-27
+ * Time: 00:04
+ * Version: 1.0
+ */
+public class MentionFriendsNameFragment extends BaseFragment {
+
+ @InjectView(R.id.et_search_input)
+ EditText mEtSearchInput;
+
+ @InjectView(R.id.lv_friends)
+ StickyListHeadersListView mLvFriends;
+
+ @InjectView(R.id.ll_choose_friend_avatars)
+ LinearLayout mLLChooseFriendAvatars;
+
+ @InjectView(R.id.lb_indexer)
+ IndexerBar mIndexerBar;
+
+ @InjectView(R.id.tv_letter_tips)
+ TextView mTipsView;
+
+ @InjectView(R.id.tv_search_empty)
+ TextView mSearchEmpty;
+
+ @InjectView(R.id.error_layout)
+ EmptyLayout mErrorLayout;
+
+ private TextView mBtnConfirm;
+
+ private SparseArray mAvatarViews;
+ private List mFriendList;
+
+ private InitialAdapter mInitialAdapter;
+ private InitialAdapter mSearchAdapter;
+ private InitialAdapter mCurrentAdapter;
+
+ private boolean mFirstChoose = true;
+ private int mPrimaryInputPaddingLeft;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.fragment_mention_friends_name, container, false);
+ initLayout(view);
+ return view;
+ }
+
+ private void initLayout(View view){
+ ButterKnife.inject(this, view);
+
+ initConfirmButton();
+
+ // 关闭列表滑块
+ mLvFriends.setVerticalScrollBarEnabled(false);
+
+ mAvatarViews = new SparseArray<>();
+
+ mEtSearchInput.addTextChangedListener(mTextWatcher);
+
+ mSearchAdapter = new InitialAdapter(getActivity(), null);
+ mSearchAdapter.setOnChooseChangeListener(mOnChooseChangeListener);
+
+ mIndexerBar.setIndexes("☆ABCDEFGHIJKLMNOPQRSTUVWXYZ#");
+ mIndexerBar.attachLetterTipsView(mTipsView);
+ mIndexerBar.setOnSelectListener(mLetterSelectListener);
+
+ mErrorLayout.setOnLayoutClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ mState = STATE_REFRESH;
+ mErrorLayout.setErrorType(EmptyLayout.NETWORK_LOADING);
+ loadData();
+ }
+ });
+
+ loadData();
+ }
+
+ private void initConfirmButton(){
+ mBtnConfirm = new TextView(getActivity());
+ mBtnConfirm.setText(getConfirmStr(0));
+ mBtnConfirm.setTextColor(Color.WHITE);
+ mBtnConfirm.setTextSize(12);
+ mBtnConfirm.setGravity(Gravity.CENTER);
+ mBtnConfirm.setBackgroundResource(R.drawable.btn_mention_friends_selector);
+ mBtnConfirm.setOnClickListener(mConfirmListener);
+ mBtnConfirm.setEnabled(false);
+ ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
+ actionBar.setDisplayShowCustomEnabled(true);
+ ActionBar.LayoutParams params = new ActionBar.LayoutParams(
+ ActionBar.LayoutParams.WRAP_CONTENT,
+ ActionBar.LayoutParams.WRAP_CONTENT
+ );
+ params.gravity = Gravity.CENTER | Gravity.RIGHT;
+ params.setMargins(0, 0, Util.dpToPx(4, getResources()), 0);
+ actionBar.setCustomView(mBtnConfirm, params);
+ }
+
+ private void loadData(){
+ OSChinaApi.getFriendList(AppContext.getInstance().getLoginUid(), mHandler);
+ }
+
+ private TextWatcher mTextWatcher = new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+
+ }
+
+ @Override
+ public void afterTextChanged(Editable editable) {
+ if (isEmpty(mFriendList))
+ return;
+ if (editable.length() == 0){
+ mLvFriends.setAdapter(mInitialAdapter);
+ mLvFriends.setEmptyView(null);
+ mCurrentAdapter = mInitialAdapter;
+ } else {
+ // 当搜索框有文字的时候自动搜索用户
+ mLvFriends.setAdapter(mSearchAdapter);
+ mLvFriends.setEmptyView(mSearchEmpty);
+ mSearchAdapter.setDataList(searchFriends(editable.toString()));
+ // 把已经选中的用户列表传给搜索结果列表Adapter,防止同个用户被多次选中
+ mSearchAdapter.setCheckedFriends(mInitialAdapter.getCheckedFriends());
+ mSearchAdapter.notifyDataSetChanged();
+ mCurrentAdapter = mSearchAdapter;
+ }
+ }
+ };
+
+ private View.OnClickListener mConfirmListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (isEmpty(mCurrentAdapter.getCheckedFriends())){
+ Toast.makeText(getActivity(), R.string.str_mention_tips_not_select, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ StringBuilder mMentionsBuilder = new StringBuilder();
+ for (InitialFriend friend:mFriendList){
+ if (mCurrentAdapter.getCheckedFriends().contains(friend.getUserid())){
+ mMentionsBuilder.append("@").append(friend.getName()).append(" ");
+ }
+ }
+ Intent intent = new Intent();
+ intent.putExtra(MentionFriendsNameActivity.MENTIONS, mMentionsBuilder.toString());
+ getActivity().setResult(Activity.RESULT_OK, intent);
+ getActivity().finish();
+ }
+ };
+
+ private IndexerBar.OnSelectListener mLetterSelectListener = new IndexerBar.OnSelectListener() {
+ @Override
+ public void onSelect(String s) {
+ for (int i=0; i searchFriends(String name){
+ List searchList = new ArrayList<>();
+ for (InitialFriend friend:mFriendList){
+ if (friend.getName().contains(name)){
+ searchList.add(friend);
+ }
+ }
+ return searchList;
+ }
+
+ @Override
+ public void setUserVisibleHint(boolean isVisibleToUser) {
+ super.setUserVisibleHint(isVisibleToUser);
+ }
+
+ protected AsyncHttpResponseHandler mHandler = new AsyncHttpResponseHandler() {
+
+ @Override
+ public void onSuccess(int statusCode, Header[] headers,
+ byte[] responseBytes) {
+ FriendsList list = XmlUtils.toBean(FriendsList.class, responseBytes);
+ if (isEmpty(list.getList())){
+ mErrorLayout.setErrorType(EmptyLayout.NODATA);
+ } else {
+ mFriendList = makeInitialFriends(list.getFriendlist());
+ mInitialAdapter = new InitialAdapter(getActivity(), mFriendList);
+ mInitialAdapter.setOnChooseChangeListener(mOnChooseChangeListener);
+ mLvFriends.setAdapter(mInitialAdapter);
+ mCurrentAdapter = mInitialAdapter;
+
+ mErrorLayout.setErrorType(EmptyLayout.HIDE_LAYOUT);
+ mBtnConfirm.setEnabled(true);
+ }
+ }
+
+ @Override
+ public void onFailure(int arg0, Header[] arg1, byte[] arg2,
+ Throwable arg3) {
+ if (isAdded()) {
+// readCacheData(getCacheKey());
+ mErrorLayout.setErrorType(EmptyLayout.NETWORK_ERROR);
+ }
+ }
+ };
+
+ private FriendsAdapter.OnChooseChangeListener mOnChooseChangeListener = new FriendsAdapter.OnChooseChangeListener() {
+
+ @Override
+ public void onAdd(InitialFriend friend, int count) {
+ setInputPaddingLeft(count);
+ addPreview(friend);
+ mBtnConfirm.setText(getConfirmStr(count));
+ }
+
+ @Override
+ public void onRemove(InitialFriend friend, int count) {
+ setInputPaddingLeft(count);
+ removePreview(friend);
+ mBtnConfirm.setText(getConfirmStr(count));
+ }
+ };
+
+ /**
+ * 添加头像到输入框预览列表
+ * @param friend
+ */
+ private void addPreview(InitialFriend friend){
+ int size = getDimension(R.dimen.choose_friend_avatar_size);
+ SquareAvatarView view = new SquareAvatarView(getActivity());
+ view.setLayoutParams(new LinearLayout.LayoutParams(size, size));
+ view.setAvatarUrl(friend.getPortrait());
+ mAvatarViews.put(friend.getUserid(), view);
+ mLLChooseFriendAvatars.addView(view);
+ }
+
+ /**
+ * 移除输入框预览列表的头像
+ * @param friend
+ */
+ private void removePreview(InitialFriend friend){
+ mLLChooseFriendAvatars.removeView(mAvatarViews.get(friend.getUserid()));
+ mAvatarViews.remove(friend.getUserid());
+ }
+
+ /**
+ * 设置输入框的左内边距,让光标和提示语不会被预览列表挡住
+ * @param count
+ */
+ private void setInputPaddingLeft(int count){
+ // 第一次设置的时候先记录原始的左内边距
+ if (mFirstChoose){
+ mFirstChoose = false;
+ mPrimaryInputPaddingLeft = mEtSearchInput.getPaddingLeft();
+ }
+ mEtSearchInput.setPadding(
+ count * getDimension(R.dimen.choose_friend_avatar_size) + mPrimaryInputPaddingLeft,
+ mEtSearchInput.getPaddingTop(),
+ mEtSearchInput.getPaddingRight(),
+ mEtSearchInput.getPaddingBottom()
+ );
+ }
+
+ private int getDimension(int resId){
+ return getResources().getDimensionPixelSize(resId);
+ }
+
+ /**
+ * 转换为带名字首字母的实体类
+ * @param friends
+ * @return
+ */
+ private List makeInitialFriends(List friends){
+ List initialFriends = new ArrayList<>(friends.size());
+ for (Friend f:friends){
+ initialFriends.add(InitialFriend.make(f));
+ }
+ Collections.sort(initialFriends, new NameOrderComparator());
+ return initialFriends;
+ }
+
+ private List makeTestInitialFriends(List friends){
+ List initialFriends = new ArrayList<>(friends.size());
+ for (Friend f:friends){
+ for (int i=0; i<10; i++){
+ InitialFriend ifd = InitialFriend.make(f);
+ ifd.setUserid(f.getUserid()+i);
+ ifd.setName(f.getName() + i);
+ ifd.setInitial(String.valueOf((char)(ifd.getInitial().charAt(0)+i)));
+ initialFriends.add(ifd);
+ }
+ }
+ Collections.sort(initialFriends, new NameOrderComparator());
+ return initialFriends;
+ }
+
+ /**
+ * 根据字母顺序进行排序
+ */
+ class NameOrderComparator implements Comparator {
+
+ @Override
+ public int compare(InitialFriend lhs, InitialFriend rhs) {
+ if (lhs.getInitial().charAt(0) < rhs.getInitial().charAt(0)){
+ return -1;
+ } else {
+ return 1;
+ }
+ }
+ }
+
+ private boolean isEmpty(Collection> collection){
+ return collection == null || collection.isEmpty() ? true : false;
+ }
+
+}
diff --git a/app/src/main/java/net/oschina/app/fragment/TweetPubFragment.java b/app/src/main/java/net/oschina/app/fragment/TweetPubFragment.java
index 27558fa962309fc9eead182388be9e80cf06afb7..e8ae761fba6f468654adfb5caa9bc786af81b567 100644
--- a/app/src/main/java/net/oschina/app/fragment/TweetPubFragment.java
+++ b/app/src/main/java/net/oschina/app/fragment/TweetPubFragment.java
@@ -15,6 +15,7 @@ import android.provider.MediaStore;
import android.provider.MediaStore.Images;
import android.support.annotation.Nullable;
import android.text.TextUtils;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -30,12 +31,14 @@ import android.widget.TextView;
import net.oschina.app.AppContext;
import net.oschina.app.R;
import net.oschina.app.base.BaseFragment;
+import net.oschina.app.bean.SimpleBackPage;
import net.oschina.app.bean.Tweet;
import net.oschina.app.emoji.EmojiKeyboardFragment;
import net.oschina.app.emoji.Emojicon;
import net.oschina.app.emoji.InputHelper;
import net.oschina.app.emoji.OnEmojiClickListener;
import net.oschina.app.service.ServerTaskUtils;
+import net.oschina.app.ui.MentionFriendsNameActivity;
import net.oschina.app.util.DialogHelp;
import net.oschina.app.util.FileUtil;
import net.oschina.app.util.ImageUtils;
@@ -76,6 +79,8 @@ public class TweetPubFragment extends BaseFragment implements
private static final String TEXT_ATME = "@请输入用户名 ";
private static final String TEXT_SOFTWARE = "#请输入软件名#";
+ private static final int REQUEST_CODE_MENTION_FRIENDS_NAME = 1001;
+
private String fromSharedTextContent = "";
@InjectView(R.id.ib_emoji_keyboard)
@@ -387,7 +392,8 @@ public class TweetPubFragment extends BaseFragment implements
if (id == R.id.ib_picture) {
handleSelectPicture();
} else if (id == R.id.ib_mention) {
- insertMention();
+// insertMention();
+ mentionFriends();
} else if (id == R.id.ib_trend_software) {
insertTrendSoftware();
} else if (id == R.id.tv_clear) {
@@ -412,6 +418,11 @@ public class TweetPubFragment extends BaseFragment implements
final Intent imageReturnIntent) {
if (resultCode != Activity.RESULT_OK)
return;
+ if (requestCode == REQUEST_CODE_MENTION_FRIENDS_NAME){
+ String atNames = imageReturnIntent.getStringExtra(MentionFriendsNameActivity.MENTIONS);
+ insertMention(atNames);
+ return;
+ }
new Thread() {
private String selectedImagePath;
@@ -594,31 +605,34 @@ public class TweetPubFragment extends BaseFragment implements
}
}
- private void insertMention() {
+ private void insertMention(String atNames) {
TDevice.showSoftKeyboard(mEtInput);
// 在光标所在处插入“@用户名”
int curTextLength = mEtInput.getText().length();
if (curTextLength >= MAX_TEXT_LENGTH)
return;
- String atme = TEXT_ATME;
int start, end;
- if ((MAX_TEXT_LENGTH - curTextLength) >= atme.length()) {
+ if ((MAX_TEXT_LENGTH - curTextLength) >= atNames.length()) {
start = mEtInput.getSelectionStart() + 1;
- end = start + atme.length() - 2;
+ end = start + atNames.length() - 2;
} else {
int num = MAX_TEXT_LENGTH - curTextLength;
- if (num < atme.length()) {
- atme = atme.substring(0, num);
+ if (num < atNames.length()) {
+ atNames = atNames.substring(0, num);
}
start = mEtInput.getSelectionStart() + 1;
- end = start + atme.length() - 1;
+ end = start + atNames.length() - 1;
}
if (start > MAX_TEXT_LENGTH || end > MAX_TEXT_LENGTH) {
start = MAX_TEXT_LENGTH;
end = MAX_TEXT_LENGTH;
}
- mEtInput.getText().insert(mEtInput.getSelectionStart(), atme);
- mEtInput.setSelection(start, end);// 设置选中文字
+ mEtInput.getText().insert(mEtInput.getSelectionStart(), atNames);
+ // mEtInput.setSelection(start, end);// 设置选中文字
+ }
+
+ private void mentionFriends(){
+ UIHelper.showMentionFriendsNameActivity(getActivity(), REQUEST_CODE_MENTION_FRIENDS_NAME, SimpleBackPage.MENTION_FRIENDS_NAME);
}
private void insertTrendSoftware() {
@@ -657,4 +671,12 @@ public class TweetPubFragment extends BaseFragment implements
public void onEmojiClick(Emojicon v) {
InputHelper.input2OSC(mEtInput, v);
}
+
+ @Override
+ public void startActivityForResult(Intent intent, int requestCode) {
+ if (requestCode == REQUEST_CODE_MENTION_FRIENDS_NAME){
+ Log.e("startActivityForResult", "REQUEST_CODE_MENTION_FRIENDS_NAME");
+ }
+ super.startActivityForResult(intent, requestCode);
+ }
}
diff --git a/app/src/main/java/net/oschina/app/ui/MentionFriendsNameActivity.java b/app/src/main/java/net/oschina/app/ui/MentionFriendsNameActivity.java
new file mode 100644
index 0000000000000000000000000000000000000000..0ed17ce8b74474e9501e8e02bc1a49949ba21aa0
--- /dev/null
+++ b/app/src/main/java/net/oschina/app/ui/MentionFriendsNameActivity.java
@@ -0,0 +1,27 @@
+package net.oschina.app.ui;
+
+import android.content.Intent;
+import android.os.Bundle;
+
+/**
+ * Description:
+ * User: ZhengXingtian(lan4627@Gmail.com)
+ * Date: 2015-08-26
+ * Time: 23:51
+ * Version: 1.0
+ */
+public class MentionFriendsNameActivity extends SimpleBackActivity {
+
+ public static final String MENTIONS = "mentions";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ }
+
+ @Override
+ public void finish() {
+ super.finish();
+ }
+}
diff --git a/app/src/main/java/net/oschina/app/ui/TweetActivity.java b/app/src/main/java/net/oschina/app/ui/TweetActivity.java
index e3f2c329109807a4bf615ae9b4d5853eff3b968c..93862fe55d535b2e2f027105a7ff98e33fefaf55 100644
--- a/app/src/main/java/net/oschina/app/ui/TweetActivity.java
+++ b/app/src/main/java/net/oschina/app/ui/TweetActivity.java
@@ -21,6 +21,13 @@ public class TweetActivity extends SimpleBackActivity {
public static String FROM_KEY = "image_shared_key";
+ @Override
+ protected void onActivityResult(int arg0, int arg1, Intent arg2) {
+ if (currentFragment != null)
+ currentFragment.onActivityResult(arg0, arg1, arg2);
+ super.onActivityResult(arg0, arg1, arg2);
+ }
+
@Override
protected void onCreate(Bundle savedInstanceState) {
Intent intent = getIntent();
diff --git a/app/src/main/java/net/oschina/app/util/FirstLatterUtil.java b/app/src/main/java/net/oschina/app/util/FirstLatterUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..1131b427f33ecd20cba2a9a6a385ee9953357a2f
--- /dev/null
+++ b/app/src/main/java/net/oschina/app/util/FirstLatterUtil.java
@@ -0,0 +1,98 @@
+package net.oschina.app.util;
+
+/**
+ * Description:
+ * User: ZhengXingtian(lan4627@Gmail.com)
+ * Date: 2015-08-27
+ * Time: 02:30
+ * Version: 1.0
+ * 来自:不充电就面壁 http://blog.csdn.net/leeyefang/article/details/9082255
+ */
+public class FirstLatterUtil {
+
+ private static int BEGIN = 45217;
+ private static int END = 63486;
+ // 按照声母表示,这个表是在GB2312中的出现的第一个汉字,也就是说“啊”是代表首字母a的第一个汉字。
+ // i, u, v都不做声母, 自定规则跟随前面的字母
+ private static char[] chartable = {'啊', '芭', '擦', '搭', '蛾', '发', '噶', '哈',
+ '哈', '击', '喀', '垃', '妈', '拿', '哦', '啪', '期', '然', '撒', '塌', '塌',
+ '塌', '挖', '昔', '压', '匝',};
+ // 二十六个字母区间对应二十七个端点
+ // GB2312码汉字区间十进制表示
+ private static int[] table = new int[27];
+ // 对应首字母区间表
+ private static char[] initialtable = {'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'h', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+ 't', 't', 'w', 'x', 'y', 'z',};
+ // 初始化
+ static {
+ for (int i = 0; i < 26; i++) {
+ table[i] = gbValue(chartable[i]);// 得到GB2312码的首字母区间端点表,十进制。
+ }
+ table[26] = END;// 区间表结尾
+ }
+ /**
+ * 根据一个包含汉字的字符串返回一个汉字拼音首字母的字符串 最重要的一个方法,思路如下:一个个字符读入、判断、输出
+ */
+ public static String getFirstLetter(String sourceStr) {
+ String result = "";
+ String str = sourceStr.toLowerCase();
+ int StrLength = str.length();
+ int i;
+ try {
+ for (i = 0; i < StrLength; i++) {
+ result += Char2Initial(str.charAt(i));
+ }
+ } catch (Exception e) {
+ result = "";
+ }
+ return result;
+ }
+ /**
+ * 输入字符,得到他的声母,英文字母返回对应的大写字母,其他非简体汉字返回 '0'
+ */
+ private static char Char2Initial(char ch) {
+ // 对英文字母的处理:小写字母转换为大写,大写的直接返回
+ if (ch >= 'a' && ch <= 'z') {
+ return ch;
+ }
+ if (ch >= 'A' && ch <= 'Z') {
+ return ch;
+ }
+ // 对非英文字母的处理:转化为首字母,然后判断是否在码表范围内,
+ // 若不是,则直接返回。
+ // 若是,则在码表内的进行判断。
+ int gb = gbValue(ch);// 汉字转换首字母
+ if ((gb < BEGIN) || (gb > END))// 在码表区间之前,直接返回
+ {
+ return ch;
+ }
+ int i;
+ for (i = 0; i < 26; i++) {// 判断匹配码表区间,匹配到就break,判断区间形如“[,)”
+ if ((gb >= table[i]) && (gb < table[i + 1])) {
+ break;
+ }
+ }
+ if (gb == END) {//补上GB2312区间最右端
+ i = 25;
+ }
+ return initialtable[i]; // 在码表区间中,返回首字母
+ }
+ /**
+ * 取出汉字的编码 cn 汉字
+ */
+ private static int gbValue(char ch) {// 将一个汉字(GB2312)转换为十进制表示。
+ String str = new String();
+ str += ch;
+ try {
+ byte[] bytes = str.getBytes("GB2312");
+ if (bytes.length < 2) {
+ return 0;
+ }
+ return (bytes[0] << 8 & 0xff00) + (bytes[1] & 0xff);
+ } catch (Exception e) {
+ return 0;
+ }
+ }
+
+}
diff --git a/app/src/main/java/net/oschina/app/util/UIHelper.java b/app/src/main/java/net/oschina/app/util/UIHelper.java
index 03f3ce0b3742bc0116021bef01ef16cfb56be30e..e843ceee6ea5f622a9069934ce11c92952e3cd12 100644
--- a/app/src/main/java/net/oschina/app/util/UIHelper.java
+++ b/app/src/main/java/net/oschina/app/util/UIHelper.java
@@ -68,6 +68,7 @@ import net.oschina.app.ui.DetailActivity;
import net.oschina.app.ui.EventLocationActivity;
import net.oschina.app.ui.ImagePreviewActivity;
import net.oschina.app.ui.LoginActivity;
+import net.oschina.app.ui.MentionFriendsNameActivity;
import net.oschina.app.ui.SimpleBackActivity;
import net.oschina.app.ui.TweetActivity;
import net.oschina.app.viewpagerfragment.FriendsViewPagerFragment;
@@ -346,7 +347,7 @@ public class UIHelper {
@JavascriptInterface
public void showImagePreview(String bigImageUrl) {
if (bigImageUrl != null && !StringUtils.isEmpty(bigImageUrl)) {
- UIHelper.showImagePreview(cxt, new String[] { bigImageUrl });
+ UIHelper.showImagePreview(cxt, new String[]{bigImageUrl});
}
}
}, "mWebViewImageListener");
@@ -591,6 +592,12 @@ public class UIHelper {
context.startActivity(intent);
}
+ public static void showMentionFriendsNameActivity(Activity activity, int requestCode, SimpleBackPage page){
+ Intent intent = new Intent(activity, MentionFriendsNameActivity.class);
+ intent.putExtra(SimpleBackActivity.BUNDLE_KEY_PAGE, page.getValue());
+ activity.startActivityForResult(intent, requestCode);
+ }
+
public static void showComment(Context context, int id, int catalog) {
Intent intent = new Intent(context, DetailActivity.class);
intent.putExtra(CommentFrament.BUNDLE_KEY_ID, id);
diff --git a/app/src/main/java/net/oschina/app/widget/IndexerBar.java b/app/src/main/java/net/oschina/app/widget/IndexerBar.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ebd8c7b45e9f92d2b6f83fc42c1fa4c189d94ad
--- /dev/null
+++ b/app/src/main/java/net/oschina/app/widget/IndexerBar.java
@@ -0,0 +1,163 @@
+package net.oschina.app.widget;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.TextView;
+
+import net.oschina.app.widget.tooglebutton.rebound.ui.Util;
+
+/**
+ * Description:
+ * User: ZhengXingtian(lan4627@Gmail.com)
+ * Date: 2015-08-28
+ * Time: 00:02
+ * Version: 1.0
+ */
+public class IndexerBar extends View {
+
+ private static final String INDEX = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ private String[] mIndexes;
+
+ public IndexerBar(Context context) {
+ super(context);
+ init(context);
+ }
+
+ public IndexerBar(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context);
+ }
+
+ public IndexerBar(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context);
+ }
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public IndexerBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ init(context);
+ }
+
+ private TextView mTipsView;
+ private Paint mTextPaint;
+ private Rect mRect;
+ private int mDividerHeight;
+ private boolean mTouched;
+ private int mTextTotalHeight;
+
+ private void init(Context context){
+ mTextPaint = new Paint();
+ mTextPaint.setColor(Color.BLACK);
+ mTextPaint.setAntiAlias(true);
+ mTextPaint.setTextSize(Util.dpToPx(10, getResources()));
+
+ mRect = new Rect();
+ // 字母之间的距离
+ mDividerHeight = Util.dpToPx(8, getResources());
+
+ setIndexes(INDEX);
+ }
+
+ public void setIndexes(String str){
+ mIndexes = new String[str.length()];
+ for (int i=0; i= mIndexes.length){
+ setTouched(false);
+ return false;
+ }
+ setLetterTipsView(mIndexes[index]);
+ switch (event.getAction()){
+ case MotionEvent.ACTION_DOWN:
+ setTouched(true);
+ break;
+
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ setTouched(false);
+ break;
+ }
+
+ if (mOnSelectListener != null){
+ mOnSelectListener.onSelect(mIndexes[index]);
+ }
+ return true;
+ }
+
+ private void setTouched(boolean touched){
+ mTouched = touched;
+ if (touched){
+ showLetterTipsView();
+ } else {
+ hideLetterTipsView();
+ }
+ // 重新绘制,让背景变色
+ invalidate();
+ }
+
+ public void attachLetterTipsView(TextView tipsView){
+ mTipsView = tipsView;
+ }
+
+ private void setLetterTipsView(String s){
+ if (mTipsView != null)
+ mTipsView.setText(s);
+ }
+
+ private void showLetterTipsView(){
+ if (mTipsView != null)
+ mTipsView.setVisibility(VISIBLE);
+ }
+
+ private void hideLetterTipsView(){
+ if (mTipsView != null)
+ mTipsView.setVisibility(INVISIBLE);
+ }
+
+ private OnSelectListener mOnSelectListener;
+
+ public void setOnSelectListener(OnSelectListener l){
+ mOnSelectListener = l;
+ }
+
+ public interface OnSelectListener{
+ void onSelect(String s);
+ }
+}
diff --git a/app/src/main/java/net/oschina/app/widget/SquareAvatarView.java b/app/src/main/java/net/oschina/app/widget/SquareAvatarView.java
new file mode 100644
index 0000000000000000000000000000000000000000..246ff4f3cc259026763482b2516ce96900f163d4
--- /dev/null
+++ b/app/src/main/java/net/oschina/app/widget/SquareAvatarView.java
@@ -0,0 +1,99 @@
+package net.oschina.app.widget;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Context;
+import android.os.Build;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageView;
+
+import net.oschina.app.R;
+import net.oschina.app.util.UIHelper;
+
+import org.kymjs.kjframe.KJBitmap;
+import org.kymjs.kjframe.bitmap.BitmapCallBack;
+import org.kymjs.kjframe.utils.StringUtils;
+
+/**
+ * Description:
+ * User: ZhengXingtian(lan4627@Gmail.com)
+ * Date: 2015-08-27
+ * Time: 02:08
+ * Version: 1.0
+ */
+public class SquareAvatarView extends ImageView {
+
+ public SquareAvatarView(Context context) {
+ super(context);
+ init(context);
+ }
+
+ public SquareAvatarView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context);
+ }
+
+ public SquareAvatarView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context);
+ }
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public SquareAvatarView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ init(context);
+ }
+ private static KJBitmap sKJB = new KJBitmap();
+ private Activity mActivity;
+ private int mUserId;
+ private String mUserName;
+
+ private void init(Context context){
+ mActivity = (Activity) context;
+ setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!TextUtils.isEmpty(mUserName)) {
+ UIHelper.showUserCenter(getContext(), mUserId, mUserName);
+ }
+ }
+ });
+ }
+
+ public void setUserInfo(int id, String name) {
+ mUserId = id;
+ mUserName = name;
+ }
+
+ public void setAvatarUrl(String url) {
+ if (StringUtils.isEmpty(url)) {
+ setImageResource(R.drawable.widget_dface);
+ return;
+ }
+ // 由于头像地址默认加了一段参数需要去掉
+ int end = url.indexOf('?');
+ final String headUrl;
+ if (end > 0) {
+ headUrl = url.substring(0, end);
+ } else {
+ headUrl = url;
+ }
+
+ sKJB.display(this, headUrl, R.drawable.widget_dface, 0, 0,
+ new BitmapCallBack() {
+ @Override
+ public void onFailure(Exception e) {
+ super.onFailure(e);
+ mActivity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ setImageResource(R.drawable.widget_dface);
+ }
+ });
+ setImageResource(R.drawable.widget_dface);
+ }
+ });
+ }
+}
diff --git a/app/src/main/res/drawable/background_btn_mention_friends_confirm_normal.xml b/app/src/main/res/drawable/background_btn_mention_friends_confirm_normal.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8187f055414984f0630ee90904e10fc80161a109
--- /dev/null
+++ b/app/src/main/res/drawable/background_btn_mention_friends_confirm_normal.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/background_btn_mention_friends_confirm_pressed.xml b/app/src/main/res/drawable/background_btn_mention_friends_confirm_pressed.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0ac0b8de5400d2951e3a498ab06c2be2f0abef9c
--- /dev/null
+++ b/app/src/main/res/drawable/background_btn_mention_friends_confirm_pressed.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/background_view_letter_tips.xml b/app/src/main/res/drawable/background_view_letter_tips.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c6dc126f56ffe38f57ccb6cf260923fdc01920c0
--- /dev/null
+++ b/app/src/main/res/drawable/background_view_letter_tips.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/btn_mention_friends_selector.xml b/app/src/main/res/drawable/btn_mention_friends_selector.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ef0634ffcea39da1157b896a44d4e2ee74b968be
--- /dev/null
+++ b/app/src/main/res/drawable/btn_mention_friends_selector.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_mention_friends_name.xml b/app/src/main/res/layout/fragment_mention_friends_name.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e6381113924b33231d721a38f0679f2cb5889e58
--- /dev/null
+++ b/app/src/main/res/layout/fragment_mention_friends_name.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_choose_friend.xml b/app/src/main/res/layout/item_choose_friend.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dfe8cf59362683a81fb4b878bd85fb0196d4c131
--- /dev/null
+++ b/app/src/main/res/layout/item_choose_friend.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_mention_friends_name_head.xml b/app/src/main/res/layout/item_mention_friends_name_head.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3c3efbb5c3e56c711f15602c27427457f3accf50
--- /dev/null
+++ b/app/src/main/res/layout/item_mention_friends_name_head.xml
@@ -0,0 +1,11 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 4df8e5e3f0172a373d867a0655cee1401007e561..f5d71a78b0481d6f0561f2f564b672de8f7cd3d1 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -90,4 +90,6 @@
#464646
#6baf77
+
+ #46000000
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 58d7807c6b529f9183f5a957c82c77a49da4ba5d..69e75d85438657d1555a223bdb84cf2c879a9164 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -140,6 +140,8 @@
48dip
24dip
+ 33dp
+
- 0.82
- 0.85
- 0.16
@@ -151,4 +153,4 @@
- 0.14
- 0.11
-
+
\ No newline at end of file
diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml
index 66103ea25835a5161b9abc7e52ba7769f507c1b5..ad1f034f8884a87b3c6a2db2708ada5f6ca3702f 100644
--- a/app/src/main/res/values/ids.xml
+++ b/app/src/main/res/values/ids.xml
@@ -8,5 +8,6 @@
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index eea0b4c9d0bd5bd5511b4404c569c7c4c91e2e3c..2607077e8e3cb235f44ec2c49ea86defdf1c451d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -150,6 +150,8 @@
编辑便签
摇一摇
搜索
+ 选择@好友
+
活动
@@ -303,4 +305,8 @@
选择团队
我的任务
+
+ 搜索
+ 确定
+ 请至少选择一个好友