improved enter key behaviour in messages conversion and quick search bar
This commit is contained in:
parent
68ba8d458c
commit
0dce3fcdd5
|
@ -61,13 +61,13 @@ import android.support.v7.widget.RecyclerView.ItemDecoration;
|
|||
import android.support.v7.widget.RecyclerView.State;
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.ActionMode;
|
||||
import android.view.ActionMode.Callback;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
|
@ -75,15 +75,12 @@ import android.view.MenuItem;
|
|||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnKeyListener;
|
||||
import android.view.View.OnLongClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TextView.OnEditorActionListener;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.nostra13.universalimageloader.utils.IoUtils;
|
||||
|
@ -109,6 +106,8 @@ import org.mariotaku.twidere.service.BackgroundOperationService;
|
|||
import org.mariotaku.twidere.util.AsyncTaskUtils;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.ContentValuesCreator;
|
||||
import org.mariotaku.twidere.util.EditTextEnterHandler;
|
||||
import org.mariotaku.twidere.util.EditTextEnterHandler.EnterListener;
|
||||
import org.mariotaku.twidere.util.MathUtils;
|
||||
import org.mariotaku.twidere.util.MediaLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.MenuUtils;
|
||||
|
@ -600,29 +599,12 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL
|
|||
}
|
||||
mMenuBar.setOnMenuItemClickListener(this);
|
||||
final boolean sendByEnter = mPreferences.getBoolean(KEY_QUICK_SEND);
|
||||
mEditText.setOnKeyListener(new OnKeyListener() {
|
||||
EditTextEnterHandler.attach(mEditText, new EnterListener() {
|
||||
@Override
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_ENTER && sendByEnter && event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
updateStatus();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
public void onHitEnter() {
|
||||
updateStatus();
|
||||
}
|
||||
});
|
||||
mEditText.setOnEditorActionListener(new OnEditorActionListener() {
|
||||
|
||||
@Override
|
||||
public boolean onEditorAction(final TextView view, final int actionId, final KeyEvent event) {
|
||||
if (sendByEnter) {
|
||||
if (event != null && actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
updateStatus();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}, sendByEnter);
|
||||
mEditText.addTextChangedListener(new TextWatcher() {
|
||||
|
||||
@Override
|
||||
|
@ -638,11 +620,6 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL
|
|||
|
||||
@Override
|
||||
public void afterTextChanged(final Editable s) {
|
||||
final int length = s.length();
|
||||
if (sendByEnter && length > 0 && s.charAt(length - 1) == '\n') {
|
||||
s.delete(length - 1, length);
|
||||
updateStatus();
|
||||
}
|
||||
}
|
||||
});
|
||||
mEditText.setCustomSelectionActionModeCallback(this);
|
||||
|
@ -743,8 +720,8 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL
|
|||
startLocationUpdateIfEnabled();
|
||||
setMenu();
|
||||
updateTextCount();
|
||||
final int text_size = mPreferences.getInt(KEY_TEXT_SIZE, Utils.getDefaultTextSize(this));
|
||||
mEditText.setTextSize(text_size * 1.25f);
|
||||
final int textSize = mPreferences.getInt(KEY_TEXT_SIZE, Utils.getDefaultTextSize(this));
|
||||
mEditText.setTextSize(textSize * 1.25f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -874,16 +851,16 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL
|
|||
}
|
||||
}
|
||||
mEditText.setText(Utils.getShareStatus(this, extraSubject, extraText));
|
||||
final int selection_end = mEditText.length();
|
||||
mEditText.setSelection(selection_end);
|
||||
final int selectionEnd = mEditText.length();
|
||||
mEditText.setSelection(selectionEnd);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean handleEditDraftIntent(final DraftItem draft) {
|
||||
if (draft == null) return false;
|
||||
mEditText.setText(draft.text);
|
||||
final int selection_end = mEditText.length();
|
||||
mEditText.setSelection(selection_end);
|
||||
final int selectionEnd = mEditText.length();
|
||||
mEditText.setSelection(selectionEnd);
|
||||
mAccountsAdapter.setSelectedAccountIds(draft.account_ids);
|
||||
if (draft.media != null) {
|
||||
addMedia(Arrays.asList(draft.media));
|
||||
|
|
|
@ -785,10 +785,10 @@ public class HomeActivity extends BaseActionBarActivity implements OnClickListen
|
|||
return true;
|
||||
}
|
||||
|
||||
private void setTabPosition(final int initial_tab) {
|
||||
private void setTabPosition(final int initialTab) {
|
||||
final boolean rememberPosition = mPreferences.getBoolean(KEY_REMEMBER_POSITION, true);
|
||||
if (initial_tab >= 0) {
|
||||
mViewPager.setCurrentItem(MathUtils.clamp(initial_tab, mPagerAdapter.getCount(), 0));
|
||||
if (initialTab >= 0) {
|
||||
mViewPager.setCurrentItem(MathUtils.clamp(initialTab, mPagerAdapter.getCount(), 0));
|
||||
} else if (rememberPosition) {
|
||||
final int position = mPreferences.getInt(KEY_SAVED_TAB_POSITION, 0);
|
||||
mViewPager.setCurrentItem(MathUtils.clamp(position, mPagerAdapter.getCount(), 0));
|
||||
|
|
|
@ -35,7 +35,6 @@ import android.text.Editable;
|
|||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
|
@ -51,7 +50,6 @@ import android.widget.ImageView;
|
|||
import android.widget.ListView;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TextView.OnEditorActionListener;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
|
@ -68,6 +66,8 @@ import org.mariotaku.twidere.model.ParcelableUser.CachedIndices;
|
|||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.SavedSearches;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.SearchHistory;
|
||||
import org.mariotaku.twidere.util.EditTextEnterHandler;
|
||||
import org.mariotaku.twidere.util.EditTextEnterHandler.EnterListener;
|
||||
import org.mariotaku.twidere.util.MediaLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ParseUtils;
|
||||
import org.mariotaku.twidere.util.SwipeDismissListViewTouchListener;
|
||||
|
@ -87,8 +87,8 @@ import static org.mariotaku.twidere.util.UserColorNameUtils.getUserNickname;
|
|||
* Created by mariotaku on 15/1/6.
|
||||
*/
|
||||
public class QuickSearchBarActivity extends ThemedFragmentActivity implements OnClickListener,
|
||||
OnEditorActionListener, LoaderCallbacks<List<SuggestionItem>>, TextWatcher,
|
||||
OnItemSelectedListener, OnItemClickListener, DismissCallbacks, OnFitSystemWindowsListener {
|
||||
LoaderCallbacks<List<SuggestionItem>>, OnItemSelectedListener, OnItemClickListener,
|
||||
DismissCallbacks, OnFitSystemWindowsListener {
|
||||
|
||||
private Spinner mAccountSpinner;
|
||||
private EditText mSearchQuery;
|
||||
|
@ -98,11 +98,6 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
|
|||
private ExtendedRelativeLayout mMainContent;
|
||||
private Rect mSystemWindowsInsets = new Rect();
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDismiss(int position) {
|
||||
return mUsersSearchAdapter.canDismiss(position);
|
||||
|
@ -124,28 +119,6 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
|
|||
getSupportLoaderManager().restartLoader(0, null, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFitSystemWindows(Rect insets) {
|
||||
mSystemWindowsInsets.set(insets);
|
||||
updateWindowAttributes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
final SuggestionItem item = mUsersSearchAdapter.getItem(position);
|
||||
item.onItemClick(this, position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
getSupportLoaderManager().restartLoader(0, null, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getThemeColor() {
|
||||
return ThemeUtils.getUserAccentColor(this);
|
||||
|
@ -156,43 +129,6 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
|
|||
return ThemeUtils.getQuickSearchBarThemeResource(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_quick_search_bar);
|
||||
final List<ParcelableAccount> accounts = ParcelableAccount.getAccountsList(this, false);
|
||||
final AccountsSpinnerAdapter accountsSpinnerAdapter = new AccountsSpinnerAdapter(this, R.layout.spinner_item_account_icon);
|
||||
accountsSpinnerAdapter.setDropDownViewResource(R.layout.list_item_user);
|
||||
accountsSpinnerAdapter.addAll(accounts);
|
||||
mAccountSpinner.setAdapter(accountsSpinnerAdapter);
|
||||
mAccountSpinner.setOnItemSelectedListener(this);
|
||||
if (savedInstanceState == null) {
|
||||
final Intent intent = getIntent();
|
||||
final int index = accountsSpinnerAdapter.findItemPosition(intent.getLongExtra(EXTRA_ACCOUNT_ID, -1));
|
||||
if (index != -1) {
|
||||
mAccountSpinner.setSelection(index);
|
||||
}
|
||||
}
|
||||
mMainContent.setOnFitSystemWindowsListener(this);
|
||||
mUsersSearchAdapter = new SuggestionsAdapter(this);
|
||||
mSuggestionsList.setAdapter(mUsersSearchAdapter);
|
||||
mSuggestionsList.setOnItemClickListener(this);
|
||||
final SwipeDismissListViewTouchListener listener = new SwipeDismissListViewTouchListener(mSuggestionsList, this);
|
||||
mSuggestionsList.setOnTouchListener(listener);
|
||||
mSuggestionsList.setOnScrollListener(listener.makeScrollListener());
|
||||
mSearchSubmit.setOnClickListener(this);
|
||||
mSearchQuery.setOnEditorActionListener(this);
|
||||
mSearchQuery.addTextChangedListener(this);
|
||||
|
||||
getSupportLoaderManager().initLoader(0, null, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
updateWindowAttributes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
switch (v.getId()) {
|
||||
|
@ -229,15 +165,15 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if (event == null) return false;
|
||||
switch (event.getKeyCode()) {
|
||||
case KeyEvent.KEYCODE_ENTER: {
|
||||
doSearch();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
public void onFitSystemWindows(Rect insets) {
|
||||
mSystemWindowsInsets.set(insets);
|
||||
updateWindowAttributes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
final SuggestionItem item = mUsersSearchAdapter.getItem(position);
|
||||
item.onItemClick(this, position);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -250,6 +186,68 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_quick_search_bar);
|
||||
final List<ParcelableAccount> accounts = ParcelableAccount.getAccountsList(this, false);
|
||||
final AccountsSpinnerAdapter accountsSpinnerAdapter = new AccountsSpinnerAdapter(this, R.layout.spinner_item_account_icon);
|
||||
accountsSpinnerAdapter.setDropDownViewResource(R.layout.list_item_user);
|
||||
accountsSpinnerAdapter.addAll(accounts);
|
||||
mAccountSpinner.setAdapter(accountsSpinnerAdapter);
|
||||
mAccountSpinner.setOnItemSelectedListener(this);
|
||||
if (savedInstanceState == null) {
|
||||
final Intent intent = getIntent();
|
||||
final int index = accountsSpinnerAdapter.findItemPosition(intent.getLongExtra(EXTRA_ACCOUNT_ID, -1));
|
||||
if (index != -1) {
|
||||
mAccountSpinner.setSelection(index);
|
||||
}
|
||||
}
|
||||
mMainContent.setOnFitSystemWindowsListener(this);
|
||||
mUsersSearchAdapter = new SuggestionsAdapter(this);
|
||||
mSuggestionsList.setAdapter(mUsersSearchAdapter);
|
||||
mSuggestionsList.setOnItemClickListener(this);
|
||||
final SwipeDismissListViewTouchListener listener = new SwipeDismissListViewTouchListener(mSuggestionsList, this);
|
||||
mSuggestionsList.setOnTouchListener(listener);
|
||||
mSuggestionsList.setOnScrollListener(listener.makeScrollListener());
|
||||
mSearchSubmit.setOnClickListener(this);
|
||||
|
||||
EditTextEnterHandler.attach(mSearchQuery, new EnterListener() {
|
||||
@Override
|
||||
public void onHitEnter() {
|
||||
doSearch();
|
||||
}
|
||||
}, true);
|
||||
mSearchQuery.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
if (Utils.removeLineBreaks(s)) {
|
||||
doSearch();
|
||||
} else {
|
||||
getSupportLoaderManager().restartLoader(0, null, QuickSearchBarActivity.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
getSupportLoaderManager().initLoader(0, null, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
updateWindowAttributes();
|
||||
}
|
||||
|
||||
private void doSearch() {
|
||||
if (isFinishing()) return;
|
||||
final String query = ParseUtils.parseString(mSearchQuery.getText());
|
||||
|
@ -263,6 +261,10 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
|
|||
return mAccountSpinner.getSelectedItemId();
|
||||
}
|
||||
|
||||
private static int getHistorySize(CharSequence query) {
|
||||
return TextUtils.isEmpty(query) ? 3 : 2;
|
||||
}
|
||||
|
||||
private void updateWindowAttributes() {
|
||||
final Window window = getWindow();
|
||||
final WindowManager.LayoutParams attributes = window.getAttributes();
|
||||
|
@ -285,48 +287,6 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
|
|||
|
||||
}
|
||||
|
||||
static class SearchHistoryItem extends BaseClickableItem {
|
||||
|
||||
static final int ITEM_VIEW_TYPE = 0;
|
||||
private final long mCursorId;
|
||||
private final String mQuery;
|
||||
|
||||
public long getCursorId() {
|
||||
return mCursorId;
|
||||
}
|
||||
|
||||
public SearchHistoryItem(long cursorId, String query) {
|
||||
mCursorId = cursorId;
|
||||
mQuery = query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getItemLayoutResource() {
|
||||
return R.layout.list_item_suggestion_search;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType() {
|
||||
return ITEM_VIEW_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(QuickSearchBarActivity activity, int position) {
|
||||
Utils.openSearch(activity, activity.getAccountId(), mQuery);
|
||||
activity.finish();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void bindView(SuggestionsAdapter adapter, View view, int position) {
|
||||
final ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
|
||||
final TextView text1 = (TextView) view.findViewById(android.R.id.text1);
|
||||
text1.setText(mQuery);
|
||||
icon.setImageResource(R.drawable.ic_action_history);
|
||||
icon.setColorFilter(text1.getCurrentTextColor(), Mode.SRC_ATOP);
|
||||
}
|
||||
}
|
||||
|
||||
static abstract class BaseClickableItem implements SuggestionItem {
|
||||
@Override
|
||||
public final boolean isEnabled() {
|
||||
|
@ -371,91 +331,47 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
|
|||
}
|
||||
}
|
||||
|
||||
static class UserSuggestionItem extends BaseClickableItem {
|
||||
static class SearchHistoryItem extends BaseClickableItem {
|
||||
|
||||
static final int ITEM_VIEW_TYPE = 2;
|
||||
private final ParcelableUser mUser;
|
||||
static final int ITEM_VIEW_TYPE = 0;
|
||||
private final long mCursorId;
|
||||
private final String mQuery;
|
||||
|
||||
public UserSuggestionItem(Cursor c, CachedIndices i, long accountId) {
|
||||
mUser = new ParcelableUser(c, i, accountId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType() {
|
||||
return ITEM_VIEW_TYPE;
|
||||
}
|
||||
|
||||
public ParcelableUser getUser() {
|
||||
return mUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(QuickSearchBarActivity activity, int position) {
|
||||
Utils.openUserProfile(activity, mUser, null);
|
||||
activity.finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getItemLayoutResource() {
|
||||
return R.layout.list_item_suggestion_user;
|
||||
public SearchHistoryItem(long cursorId, String query) {
|
||||
mCursorId = cursorId;
|
||||
mQuery = query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(SuggestionsAdapter adapter, View view, int position) {
|
||||
final ParcelableUser user = mUser;
|
||||
final Context context = adapter.getContext();
|
||||
final MediaLoaderWrapper loader = adapter.getImageLoader();
|
||||
final ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
|
||||
final TextView text1 = (TextView) view.findViewById(android.R.id.text1);
|
||||
final TextView text2 = (TextView) view.findViewById(android.R.id.text2);
|
||||
|
||||
text1.setText(getUserNickname(context, user.id, user.name));
|
||||
text2.setVisibility(View.VISIBLE);
|
||||
text2.setText("@" + user.screen_name);
|
||||
icon.clearColorFilter();
|
||||
loader.displayProfileImage(icon, user.profile_image_url);
|
||||
}
|
||||
}
|
||||
|
||||
static class UserScreenNameItem extends BaseClickableItem {
|
||||
|
||||
static final int ITEM_VIEW_TYPE = 3;
|
||||
private final String mScreenName;
|
||||
private final long mAccountId;
|
||||
|
||||
public UserScreenNameItem(String screenName, long accountId) {
|
||||
mScreenName = screenName;
|
||||
mAccountId = accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType() {
|
||||
return ITEM_VIEW_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(QuickSearchBarActivity activity, int position) {
|
||||
Utils.openUserProfile(activity, mAccountId, -1, mScreenName, null);
|
||||
activity.finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getItemLayoutResource() {
|
||||
return R.layout.list_item_suggestion_user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(SuggestionsAdapter adapter, View view, int position) {
|
||||
final MediaLoaderWrapper loader = adapter.getImageLoader();
|
||||
final ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
|
||||
final TextView text1 = (TextView) view.findViewById(android.R.id.text1);
|
||||
final TextView text2 = (TextView) view.findViewById(android.R.id.text2);
|
||||
text1.setText('@' + mScreenName);
|
||||
text2.setVisibility(View.GONE);
|
||||
text1.setText(mQuery);
|
||||
icon.setImageResource(R.drawable.ic_action_history);
|
||||
icon.setColorFilter(text1.getCurrentTextColor(), Mode.SRC_ATOP);
|
||||
loader.cancelDisplayTask(icon);
|
||||
icon.setImageResource(R.drawable.ic_action_user);
|
||||
}
|
||||
|
||||
public long getCursorId() {
|
||||
return mCursorId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getItemLayoutResource() {
|
||||
return R.layout.list_item_suggestion_search;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType() {
|
||||
return ITEM_VIEW_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(QuickSearchBarActivity activity, int position) {
|
||||
Utils.openSearch(activity, activity.getAccountId(), mQuery);
|
||||
activity.finish();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static class SuggestionsAdapter extends BaseAdapter {
|
||||
|
@ -541,10 +457,6 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
|
|||
}
|
||||
}
|
||||
|
||||
private static int getHistorySize(CharSequence query) {
|
||||
return TextUtils.isEmpty(query) ? 3 : 2;
|
||||
}
|
||||
|
||||
public static class SuggestionsLoader extends AsyncTaskLoader<List<SuggestionItem>> {
|
||||
|
||||
private final long mAccountId;
|
||||
|
@ -625,4 +537,92 @@ public class QuickSearchBarActivity extends ThemedFragmentActivity implements On
|
|||
}
|
||||
}
|
||||
|
||||
static class UserScreenNameItem extends BaseClickableItem {
|
||||
|
||||
static final int ITEM_VIEW_TYPE = 3;
|
||||
private final String mScreenName;
|
||||
private final long mAccountId;
|
||||
|
||||
public UserScreenNameItem(String screenName, long accountId) {
|
||||
mScreenName = screenName;
|
||||
mAccountId = accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType() {
|
||||
return ITEM_VIEW_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(QuickSearchBarActivity activity, int position) {
|
||||
Utils.openUserProfile(activity, mAccountId, -1, mScreenName, null);
|
||||
activity.finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getItemLayoutResource() {
|
||||
return R.layout.list_item_suggestion_user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(SuggestionsAdapter adapter, View view, int position) {
|
||||
final MediaLoaderWrapper loader = adapter.getImageLoader();
|
||||
final ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
|
||||
final TextView text1 = (TextView) view.findViewById(android.R.id.text1);
|
||||
final TextView text2 = (TextView) view.findViewById(android.R.id.text2);
|
||||
text1.setText('@' + mScreenName);
|
||||
text2.setVisibility(View.GONE);
|
||||
icon.setColorFilter(text1.getCurrentTextColor(), Mode.SRC_ATOP);
|
||||
loader.cancelDisplayTask(icon);
|
||||
icon.setImageResource(R.drawable.ic_action_user);
|
||||
}
|
||||
}
|
||||
|
||||
static class UserSuggestionItem extends BaseClickableItem {
|
||||
|
||||
static final int ITEM_VIEW_TYPE = 2;
|
||||
private final ParcelableUser mUser;
|
||||
|
||||
public UserSuggestionItem(Cursor c, CachedIndices i, long accountId) {
|
||||
mUser = new ParcelableUser(c, i, accountId);
|
||||
}
|
||||
|
||||
public ParcelableUser getUser() {
|
||||
return mUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType() {
|
||||
return ITEM_VIEW_TYPE;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onItemClick(QuickSearchBarActivity activity, int position) {
|
||||
Utils.openUserProfile(activity, mUser, null);
|
||||
activity.finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getItemLayoutResource() {
|
||||
return R.layout.list_item_suggestion_user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(SuggestionsAdapter adapter, View view, int position) {
|
||||
final ParcelableUser user = mUser;
|
||||
final Context context = adapter.getContext();
|
||||
final MediaLoaderWrapper loader = adapter.getImageLoader();
|
||||
final ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
|
||||
final TextView text1 = (TextView) view.findViewById(android.R.id.text1);
|
||||
final TextView text2 = (TextView) view.findViewById(android.R.id.text2);
|
||||
|
||||
text1.setText(getUserNickname(context, user.id, user.name));
|
||||
text2.setVisibility(View.VISIBLE);
|
||||
text2.setText("@" + user.screen_name);
|
||||
icon.clearColorFilter();
|
||||
loader.displayProfileImage(icon, user.profile_image_url);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@ import android.text.Editable;
|
|||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
|
@ -62,7 +61,6 @@ import android.widget.ImageView.ScaleType;
|
|||
import android.widget.ListView;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TextView.OnEditorActionListener;
|
||||
|
||||
import com.squareup.otto.Bus;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
@ -91,6 +89,8 @@ import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages.Conversati
|
|||
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages.ConversationEntries;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.ClipboardUtils;
|
||||
import org.mariotaku.twidere.util.EditTextEnterHandler;
|
||||
import org.mariotaku.twidere.util.EditTextEnterHandler.EnterListener;
|
||||
import org.mariotaku.twidere.util.MediaLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ParseUtils;
|
||||
import org.mariotaku.twidere.util.ReadStateManager;
|
||||
|
@ -112,8 +112,8 @@ import static org.mariotaku.twidere.util.Utils.buildDirectMessageConversationUri
|
|||
import static org.mariotaku.twidere.util.Utils.showOkMessage;
|
||||
|
||||
public class MessagesConversationFragment extends BaseSupportFragment implements
|
||||
LoaderCallbacks<Cursor>, TextWatcher, OnClickListener, OnItemSelectedListener,
|
||||
OnEditorActionListener, MenuButtonClickListener, PopupMenu.OnMenuItemClickListener {
|
||||
LoaderCallbacks<Cursor>, OnClickListener, OnItemSelectedListener, MenuButtonClickListener,
|
||||
PopupMenu.OnMenuItemClickListener {
|
||||
|
||||
private static final int LOADER_ID_SEARCH_USERS = 1;
|
||||
|
||||
|
@ -160,6 +160,7 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
|
|||
@Override
|
||||
public Loader<List<ParcelableUser>> onCreateLoader(int id, Bundle args) {
|
||||
mUsersSearchList.setVisibility(View.GONE);
|
||||
mUsersSearchEmpty.setVisibility(View.GONE);
|
||||
mUsersSearchProgress.setVisibility(View.VISIBLE);
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID);
|
||||
final String query = args.getString(EXTRA_QUERY);
|
||||
|
@ -172,6 +173,7 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
|
|||
public void onLoadFinished(Loader<List<ParcelableUser>> loader, List<ParcelableUser> data) {
|
||||
mUsersSearchList.setVisibility(View.VISIBLE);
|
||||
mUsersSearchProgress.setVisibility(View.GONE);
|
||||
mUsersSearchEmpty.setVisibility(data == null || data.isEmpty() ? View.GONE : View.VISIBLE);
|
||||
mUsersSearchAdapter.setData(data, true);
|
||||
updateEmptyText();
|
||||
}
|
||||
|
@ -188,15 +190,6 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
|
|||
updateRefreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(final Editable s) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
|
@ -230,24 +223,6 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
|
|||
accountsSpinnerAdapter.addAll(accounts);
|
||||
mAccountSpinner.setAdapter(accountsSpinnerAdapter);
|
||||
mAccountSpinner.setOnItemSelectedListener(this);
|
||||
mUserQuery.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
final ParcelableAccount account = (ParcelableAccount) mAccountSpinner.getSelectedItem();
|
||||
mEditText.setAccountId(account.account_id);
|
||||
searchUsers(account.account_id, ParseUtils.parseString(s), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
|
||||
}
|
||||
});
|
||||
mQueryButton.setOnClickListener(this);
|
||||
mAdapter = new MessageConversationAdapter(activity);
|
||||
final LinearLayoutManager layoutManager = new FixedLinearLayoutManager(viewContext);
|
||||
|
@ -268,11 +243,8 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
|
|||
}
|
||||
});
|
||||
|
||||
if (mPreferences.getBoolean(KEY_QUICK_SEND, false)) {
|
||||
mEditText.setOnEditorActionListener(this);
|
||||
}
|
||||
mEditText.addTextChangedListener(this);
|
||||
|
||||
setupEditQuery();
|
||||
setupEditText();
|
||||
|
||||
mSendButton.setOnClickListener(this);
|
||||
mAddImageButton.setOnClickListener(this);
|
||||
|
@ -319,6 +291,80 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
|
|||
|
||||
}
|
||||
|
||||
private void setupEditQuery() {
|
||||
final EditTextEnterHandler queryEnterHandler = EditTextEnterHandler.attach(mUserQuery, new EnterListener() {
|
||||
@Override
|
||||
public void onHitEnter() {
|
||||
final ParcelableAccount account = (ParcelableAccount) mAccountSpinner.getSelectedItem();
|
||||
if (account == null) return;
|
||||
mEditText.setAccountId(account.account_id);
|
||||
searchUsers(account.account_id, ParseUtils.parseString(mUserQuery.getText()), false);
|
||||
}
|
||||
}, true);
|
||||
queryEnterHandler.addTextChangedListener(new TextWatcher() {
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
final ParcelableAccount account = (ParcelableAccount) mAccountSpinner.getSelectedItem();
|
||||
if (account == null) return;
|
||||
mEditText.setAccountId(account.account_id);
|
||||
searchUsers(account.account_id, ParseUtils.parseString(s), true);
|
||||
}
|
||||
});
|
||||
mUserQuery.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
Utils.removeLineBreaks(s);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setupEditText() {
|
||||
EditTextEnterHandler.attach(mEditText, new EnterListener() {
|
||||
@Override
|
||||
public void onHitEnter() {
|
||||
sendDirectMessage();
|
||||
}
|
||||
}, mPreferences.getBoolean(KEY_QUICK_SEND, false));
|
||||
mEditText.addTextChangedListener(new TextWatcher() {
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(final Editable s) {
|
||||
Utils.removeLineBreaks(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
|
||||
updateTextCount();
|
||||
if (mSendButton == null || s == null) return;
|
||||
mSendButton.setEnabled(mValidator.isValidTweet(s.toString()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String getDraftsTextKey(long accountId, long userId) {
|
||||
return String.format(Locale.ROOT, "text_%d_to_%d", accountId, userId);
|
||||
}
|
||||
|
@ -444,17 +490,6 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
|
|||
view.setPadding(insets.left, insets.top, insets.right, insets.bottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onEditorAction(final TextView view, final int actionId, final KeyEvent event) {
|
||||
switch (event.getKeyCode()) {
|
||||
case KeyEvent.KEYCODE_ENTER: {
|
||||
sendDirectMessage();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemSelected(final AdapterView<?> parent, final View view, final int pos, final long id) {
|
||||
final ParcelableAccount account = (ParcelableAccount) mAccountSpinner.getSelectedItem();
|
||||
|
@ -585,12 +620,6 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
|
|||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
|
||||
updateTextCount();
|
||||
if (mSendButton == null || s == null) return;
|
||||
mSendButton.setEnabled(mValidator.isValidTweet(s.toString()));
|
||||
}
|
||||
|
||||
private void updateEmptyText() {
|
||||
final boolean noQuery = mUserQuery.length() <= 0;
|
||||
|
@ -703,7 +732,11 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
|
|||
final ParcelableUser recipient = mRecipient;
|
||||
if (mAccount == null || mRecipient == null) return;
|
||||
final String message = mEditText.getText().toString();
|
||||
if (mValidator.isValidTweet(message)) {
|
||||
if (TextUtils.isEmpty(message)) {
|
||||
mEditText.setError(getString(R.string.error_message_no_content));
|
||||
} else if (mValidator.getTweetLength(message) > mValidator.getMaxTweetLength()) {
|
||||
mEditText.setError(getString(R.string.error_message_message_too_long));
|
||||
} else {
|
||||
mTwitterWrapper.sendDirectMessageAsync(account.account_id, recipient.id, message, mImageUri);
|
||||
mEditText.setText(null);
|
||||
mImageUri = null;
|
||||
|
|
|
@ -46,6 +46,7 @@ import android.nfc.NfcEvent;
|
|||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
|
@ -64,6 +65,7 @@ import android.support.v7.widget.Toolbar;
|
|||
import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
|
@ -109,6 +111,8 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Filters;
|
|||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.ColorUtils;
|
||||
import org.mariotaku.twidere.util.ContentValuesCreator;
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback;
|
||||
import org.mariotaku.twidere.util.LinkCreator;
|
||||
import org.mariotaku.twidere.util.MathUtils;
|
||||
import org.mariotaku.twidere.util.MediaLoaderWrapper;
|
||||
|
@ -145,7 +149,7 @@ import twitter4j.TwitterException;
|
|||
public class UserFragment extends BaseSupportFragment implements OnClickListener,
|
||||
OnLinkClickListener, OnSizeChangedListener, OnSharedPreferenceChangeListener,
|
||||
OnTouchListener, DrawerCallback, SupportFragmentCallback, SystemWindowsInsetsCallback,
|
||||
RefreshScrollTopInterface, OnPageChangeListener {
|
||||
RefreshScrollTopInterface, OnPageChangeListener, KeyboardShortcutCallback {
|
||||
|
||||
private static final ArgbEvaluator sArgbEvaluator = new ArgbEvaluator();
|
||||
|
||||
|
@ -189,9 +193,11 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
|||
private TextView mPagesErrorText;
|
||||
private View mProfileNameBackground;
|
||||
private View mProfileDetailsContainer;
|
||||
private SupportTabsAdapter mPagerAdapter;
|
||||
private Relationship mRelationship;
|
||||
|
||||
private SupportTabsAdapter mPagerAdapter;
|
||||
private KeyboardShortcutsHandler mKeyboardShortcutsHandler;
|
||||
|
||||
private ParcelableUser mUser = null;
|
||||
private Locale mLocale;
|
||||
private boolean mGetUserInfoLoaderInitialized, mGetFriendShipLoaderInitialized;
|
||||
|
@ -671,9 +677,13 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
|||
getSharedPreferences(USER_NICKNAME_PREFERENCES_NAME, Context.MODE_PRIVATE)
|
||||
.registerOnSharedPreferenceChangeListener(this);
|
||||
mLocale = getResources().getConfiguration().locale;
|
||||
mCardBackgroundColor = ThemeUtils.getCardBackgroundColor(activity, ThemeUtils.getThemeBackgroundOption(activity), ThemeUtils.getUserThemeBackgroundAlpha(activity));
|
||||
mCardBackgroundColor = ThemeUtils.getCardBackgroundColor(activity,
|
||||
ThemeUtils.getThemeBackgroundOption(activity),
|
||||
ThemeUtils.getUserThemeBackgroundAlpha(activity));
|
||||
mActionBarShadowColor = 0xA0000000;
|
||||
mProfileImageLoader = getApplication().getMediaLoaderWrapper();
|
||||
final TwidereApplication app = TwidereApplication.getInstance(activity);
|
||||
mProfileImageLoader = app.getMediaLoaderWrapper();
|
||||
mKeyboardShortcutsHandler = app.getKeyboardShortcutsHandler();
|
||||
final Bundle args = getArguments();
|
||||
long accountId = -1, userId = -1;
|
||||
String screenName = null;
|
||||
|
@ -1059,6 +1069,56 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
|||
mProfileDetailsContainer = view.findViewById(R.id.profile_details_container);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleKeyboardShortcutSingle(int keyCode, @NonNull KeyEvent event) {
|
||||
if (handleFragmentKeyboardShortcutSingle(keyCode, event)) return true;
|
||||
final String action = mKeyboardShortcutsHandler.getKeyAction("navigation", keyCode, event);
|
||||
if (action != null) {
|
||||
switch (action) {
|
||||
case "navigation.previous_tab": {
|
||||
final int previous = mViewPager.getCurrentItem() - 1;
|
||||
if (previous >= 0 && previous < mPagerAdapter.getCount()) {
|
||||
mViewPager.setCurrentItem(previous, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case "navigation.next_tab": {
|
||||
final int next = mViewPager.getCurrentItem() + 1;
|
||||
if (next >= 0 && next < mPagerAdapter.getCount()) {
|
||||
mViewPager.setCurrentItem(next, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return mKeyboardShortcutsHandler.handleKey(getActivity(), null, keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleKeyboardShortcutRepeat(int keyCode, int repeatCount, @NonNull KeyEvent event) {
|
||||
return handleFragmentKeyboardShortcutRepeat(keyCode, repeatCount, event);
|
||||
}
|
||||
|
||||
private boolean handleFragmentKeyboardShortcutRepeat(int keyCode, int repeatCount, @NonNull KeyEvent event) {
|
||||
final Fragment fragment = getKeyboardShortcutRecipient();
|
||||
if (fragment instanceof KeyboardShortcutCallback) {
|
||||
return ((KeyboardShortcutCallback) fragment).handleKeyboardShortcutRepeat(keyCode, repeatCount, event);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean handleFragmentKeyboardShortcutSingle(int keyCode, @NonNull KeyEvent event) {
|
||||
final Fragment fragment = getKeyboardShortcutRecipient();
|
||||
if (fragment instanceof KeyboardShortcutCallback) {
|
||||
return ((KeyboardShortcutCallback) fragment).handleKeyboardShortcutSingle(keyCode, event);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Fragment getKeyboardShortcutRecipient() {
|
||||
return getCurrentVisibleFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fitSystemWindows(Rect insets) {
|
||||
super.fitSystemWindows(insets);
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.util;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TextView.OnEditorActionListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/4/22.
|
||||
*/
|
||||
public class EditTextEnterHandler implements View.OnKeyListener, OnEditorActionListener, TextWatcher {
|
||||
|
||||
@Nullable
|
||||
private EnterListener listener;
|
||||
private boolean enabled;
|
||||
private ArrayList<TextWatcher> textWatchers;
|
||||
|
||||
public EditTextEnterHandler(@Nullable EnterListener listener, boolean enabled) {
|
||||
this.listener = listener;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public void addTextChangedListener(TextWatcher watcher) {
|
||||
if (textWatchers == null) {
|
||||
textWatchers = new ArrayList<>();
|
||||
}
|
||||
textWatchers.add(watcher);
|
||||
}
|
||||
|
||||
public static EditTextEnterHandler attach(@NonNull EditText editText, @Nullable EnterListener listener, boolean enabled) {
|
||||
final EditTextEnterHandler enterHandler = new EditTextEnterHandler(listener, enabled);
|
||||
editText.setOnKeyListener(enterHandler);
|
||||
editText.setOnEditorActionListener(enterHandler);
|
||||
editText.addTextChangedListener(enterHandler);
|
||||
return enterHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
if (textWatchers == null) return;
|
||||
for (TextWatcher textWatcher : textWatchers) {
|
||||
textWatcher.beforeTextChanged(s, start, count, after);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
if (textWatchers == null) return;
|
||||
for (TextWatcher textWatcher : textWatchers) {
|
||||
textWatcher.onTextChanged(s, start, before, count);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(final Editable s) {
|
||||
final int length = s.length();
|
||||
if (enabled && length > 0 && s.charAt(length - 1) == '\n') {
|
||||
s.delete(length - 1, length);
|
||||
if (listener != null) {
|
||||
listener.onHitEnter();
|
||||
}
|
||||
} else if (textWatchers != null) {
|
||||
for (TextWatcher textWatcher : textWatchers) {
|
||||
textWatcher.afterTextChanged(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onEditorAction(final TextView view, final int actionId, final KeyEvent event) {
|
||||
if (!enabled) return false;
|
||||
if (event != null && actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
if (listener != null) {
|
||||
listener.onHitEnter();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_ENTER && enabled && event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
if (listener != null) {
|
||||
listener.onHitEnter();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public void setListener(@Nullable EnterListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public static interface EnterListener {
|
||||
void onHitEnter();
|
||||
}
|
||||
|
||||
}
|
|
@ -81,6 +81,7 @@ import android.support.v4.view.MenuItemCompat;
|
|||
import android.support.v4.view.accessibility.AccessibilityEventCompat;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v7.widget.ShareActionProvider;
|
||||
import android.text.Editable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateFormat;
|
||||
|
@ -1501,6 +1502,17 @@ public final class Utils implements Constants, TwitterConstants {
|
|||
return textView;
|
||||
}
|
||||
|
||||
public static boolean removeLineBreaks(Editable s) {
|
||||
boolean deleted = false;
|
||||
for (int i = s.length() - 1; i >= 0; i--) {
|
||||
if (s.charAt(i) == '\n') {
|
||||
s.delete(i, i + 1);
|
||||
deleted |= true;
|
||||
}
|
||||
}
|
||||
return deleted;
|
||||
}
|
||||
|
||||
public static boolean setLastSeen(Context context, UserMentionEntity[] entities, long time) {
|
||||
if (entities == null) return false;
|
||||
boolean result = false;
|
||||
|
|
|
@ -47,7 +47,10 @@
|
|||
android:layout_marginLeft="@dimen/element_spacing_normal"
|
||||
android:layout_marginRight="@dimen/element_spacing_normal"
|
||||
android:gravity="bottom"
|
||||
android:inputType="textPersonName"/>
|
||||
android:inputType="textPersonName|textMultiLine">
|
||||
|
||||
<requestFocus/>
|
||||
</EditText>
|
||||
|
||||
<org.mariotaku.twidere.view.ActionIconButton
|
||||
android:id="@+id/query_button"
|
||||
|
@ -55,6 +58,7 @@
|
|||
android:layout_width="@dimen/element_size_normal"
|
||||
android:layout_height="@dimen/element_size_normal"
|
||||
android:layout_gravity="right"
|
||||
android:color="?android:textColorPrimary"
|
||||
android:padding="@dimen/element_spacing_normal"
|
||||
android:scaleType="centerInside"
|
||||
android:src="@drawable/ic_action_search"/>
|
||||
|
|
|
@ -63,10 +63,7 @@
|
|||
android:background="@android:color/transparent"
|
||||
android:focusable="true"
|
||||
android:hint="@string/search_hint"
|
||||
android:imeActionLabel="@android:string/search_go"
|
||||
android:imeOptions="actionSearch"
|
||||
android:inputType="text"
|
||||
android:singleLine="true">
|
||||
android:inputType="text|textMultiLine">
|
||||
|
||||
<requestFocus/>
|
||||
</EditText>
|
||||
|
|
|
@ -47,8 +47,7 @@
|
|||
android:completionThreshold="1"
|
||||
android:gravity="left|bottom"
|
||||
android:hint="@string/type_to_compose"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="textMultiLine"
|
||||
android:inputType="textShortMessage|textMultiLine"
|
||||
android:maxHeight="140dp"
|
||||
android:minHeight="?android:actionBarSize"
|
||||
android:singleLine="false"/>
|
||||
|
|
|
@ -244,6 +244,7 @@
|
|||
<string name="status_shortener">Tweet shortener</string>
|
||||
<string name="status_shortener_default">None (Abort sending)</string>
|
||||
<string name="error_message_status_too_long">Tweet too long.</string>
|
||||
<string name="error_message_message_too_long">Message too long.</string>
|
||||
<string name="error_message_no_content">No content</string>
|
||||
<string name="error_message_tweet_shorten_failed">Tweet shorten failed.</string>
|
||||
<string name="error_message_tweet_shortener_not_found">Tweet shortener not found, maybe it was uninstalled.</string>
|
||||
|
|
Loading…
Reference in New Issue