From 1896230f5cb3e86b8e6ad5d5905d2be622ee8421 Mon Sep 17 00:00:00 2001 From: Tarent Date: Fri, 28 Aug 2015 03:55:34 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BF=AB=E9=80=9F@=E5=A5=BD=E5=8F=8B=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=AE=8C=E6=88=90=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 17 +- app/src/main/AndroidManifest.xml | 5 + .../oschina/app/adapter/FriendsAdapter.java | 144 +++++++ .../oschina/app/adapter/InitialAdapter.java | 46 ++ .../net/oschina/app/api/ApiHttpClient.java | 8 +- .../oschina/app/api/remote/OSChinaApi.java | 7 + .../net/oschina/app/bean/InitialFriend.java | 39 ++ .../net/oschina/app/bean/SimpleBackPage.java | 5 +- .../fragment/MentionFriendsNameFragment.java | 392 ++++++++++++++++++ .../app/fragment/TweetPubFragment.java | 42 +- .../app/ui/MentionFriendsNameActivity.java | 27 ++ .../net/oschina/app/ui/TweetActivity.java | 7 + .../net/oschina/app/util/FirstLatterUtil.java | 98 +++++ .../java/net/oschina/app/util/UIHelper.java | 9 +- .../net/oschina/app/widget/IndexerBar.java | 163 ++++++++ .../oschina/app/widget/SquareAvatarView.java | 99 +++++ ...und_btn_mention_friends_confirm_normal.xml | 6 + ...nd_btn_mention_friends_confirm_pressed.xml | 6 + .../drawable/background_view_letter_tips.xml | 6 + .../drawable/btn_mention_friends_selector.xml | 5 + .../layout/fragment_mention_friends_name.xml | 70 ++++ .../main/res/layout/item_choose_friend.xml | 36 ++ .../layout/item_mention_friends_name_head.xml | 11 + app/src/main/res/values/colors.xml | 2 + app/src/main/res/values/dimens.xml | 4 +- app/src/main/res/values/ids.xml | 1 + app/src/main/res/values/strings.xml | 6 + 27 files changed, 1235 insertions(+), 26 deletions(-) create mode 100644 app/src/main/java/net/oschina/app/adapter/FriendsAdapter.java create mode 100644 app/src/main/java/net/oschina/app/adapter/InitialAdapter.java create mode 100644 app/src/main/java/net/oschina/app/bean/InitialFriend.java create mode 100644 app/src/main/java/net/oschina/app/fragment/MentionFriendsNameFragment.java create mode 100644 app/src/main/java/net/oschina/app/ui/MentionFriendsNameActivity.java create mode 100644 app/src/main/java/net/oschina/app/util/FirstLatterUtil.java create mode 100644 app/src/main/java/net/oschina/app/widget/IndexerBar.java create mode 100644 app/src/main/java/net/oschina/app/widget/SquareAvatarView.java create mode 100644 app/src/main/res/drawable/background_btn_mention_friends_confirm_normal.xml create mode 100644 app/src/main/res/drawable/background_btn_mention_friends_confirm_pressed.xml create mode 100644 app/src/main/res/drawable/background_view_letter_tips.xml create mode 100644 app/src/main/res/drawable/btn_mention_friends_selector.xml create mode 100644 app/src/main/res/layout/fragment_mention_friends_name.xml create mode 100644 app/src/main/res/layout/item_choose_friend.xml create mode 100644 app/src/main/res/layout/item_mention_friends_name_head.xml diff --git a/app/build.gradle b/app/build.gradle index 4f5b8271e..fa3f0b663 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 72cd19687..fc9fc4fa8 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 000000000..e1ea7ee73 --- /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 000000000..cec4df28e --- /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 59613bf92..8bf993276 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 a67188790..b6cea455e 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 000000000..1bf08b666 --- /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 7e40b7f95..0d35c97d5 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 000000000..be21e46b6 --- /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 27558fa96..e8ae761fb 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 000000000..0ed17ce8b --- /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 e3f2c3291..93862fe55 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 000000000..1131b427f --- /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 03f3ce0b3..e843ceee6 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 000000000..6ebd8c7b4 --- /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 000000000..246ff4f3c --- /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 000000000..8187f0554 --- /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 000000000..0ac0b8de5 --- /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 000000000..c6dc126f5 --- /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 000000000..ef0634ffc --- /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 000000000..e63811139 --- /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 000000000..dfe8cf593 --- /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 000000000..3c3efbb5c --- /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 4df8e5e3f..f5d71a78b 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 58d7807c6..69e75d854 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 66103ea25..ad1f034f8 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 eea0b4c9d..2607077e8 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 @@ 选择团队 我的任务 + + 搜索 + 确定 + 请至少选择一个好友 -- Gitee