Browse Source

allow touches when emoji keyboard is visible; internal overhaul

pull/61/merge
Thodoris1999 6 years ago
parent
commit
78c39fb715
  1. 24
      app/src/main/java/gr/thmmy/mthmmy/activities/create_content/CreateContentActivity.java
  2. 31
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
  3. 39
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
  4. 69
      app/src/main/java/gr/thmmy/mthmmy/editorview/EditorView.java
  5. 8
      app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiInputField.java
  6. 46
      app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiKeyboard.java
  7. 32
      app/src/main/java/gr/thmmy/mthmmy/editorview/IEmojiKeyboard.java

24
app/src/main/java/gr/thmmy/mthmmy/activities/create_content/CreateContentActivity.java

@ -8,7 +8,6 @@ import android.support.design.widget.TextInputLayout;
import android.text.InputType;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.Toast;
import gr.thmmy.mthmmy.R;
@ -20,8 +19,7 @@ import gr.thmmy.mthmmy.session.SessionManager;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import timber.log.Timber;
public class CreateContentActivity extends BaseActivity implements EmojiKeyboard.EmojiKeyboardOwner,
NewTopicTask.NewTopicTaskCallbacks {
public class CreateContentActivity extends BaseActivity implements NewTopicTask.NewTopicTaskCallbacks {
public final static String EXTRA_NEW_TOPIC_URL = "new-topic-extra";
@ -56,8 +54,7 @@ public class CreateContentActivity extends BaseActivity implements EmojiKeyboard
subjectInput.getEditText().setImeOptions(EditorInfo.IME_ACTION_DONE);
contentEditor = findViewById(R.id.main_content_editorview);
setEmojiKeyboardInputConnection(contentEditor.getInputConnection());
contentEditor.setEmojiKeyboardOwner(this);
contentEditor.setEmojiKeyboard(emojiKeyboard);
contentEditor.setOnSubmitListener(v -> {
if (newTopicUrl != null) {
boolean includeAppSignature = true;
@ -72,27 +69,10 @@ public class CreateContentActivity extends BaseActivity implements EmojiKeyboard
}
});
}
@Override
public void setEmojiKeyboardVisible(boolean visible) {
emojiKeyboard.setVisibility(visible ? View.VISIBLE : View.GONE);
}
@Override
public boolean isEmojiKeyboardVisible() {
return emojiKeyboard.getVisibility() == View.VISIBLE;
}
@Override
public void setEmojiKeyboardInputConnection(InputConnection ic) {
emojiKeyboard.setInputConnection(ic);
}
@Override
public void onBackPressed() {
if (emojiKeyboard.getVisibility() == View.VISIBLE) {
emojiKeyboard.setVisibility(View.GONE);
contentEditor.updateEmojiKeyboardVisibility();
} else {
super.onBackPressed();
}

31
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java

@ -27,7 +27,6 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageButton;
import android.widget.LinearLayout;
@ -67,8 +66,7 @@ import static gr.thmmy.mthmmy.services.NotificationService.NEW_POST_TAG;
* key {@link #BUNDLE_TOPIC_TITLE} for faster title rendering.
*/
@SuppressWarnings("unchecked")
public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFocusChangeListener,
EmojiKeyboard.EmojiKeyboardOwner {
public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFocusChangeListener {
//Activity's variables
/**
* The key to use when putting topic's url String to {@link TopicActivity}'s Bundle.
@ -180,7 +178,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
getApplicationContext(), topicPageUrl);
recyclerView.setLayoutManager(layoutManager);
topicAdapter = new TopicAdapter(this, topicItems);
topicAdapter = new TopicAdapter(this, emojiKeyboard, topicItems);
recyclerView.setAdapter(topicAdapter);
replyFAB = findViewById(R.id.topic_fab);
@ -269,16 +267,6 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
return;
} else if (emojiKeyboard.getVisibility() == View.VISIBLE) {
emojiKeyboard.setVisibility(View.GONE);
if (viewModel.isEditingPost()) {
TopicAdapter.EditMessageViewHolder vh = (TopicAdapter.EditMessageViewHolder)
recyclerView.findViewHolderForAdapterPosition(viewModel.getPostBeingEditedPosition());
vh.editEditor.updateEmojiKeyboardVisibility();
}
if (viewModel.isWritingReply()) {
TopicAdapter.QuickReplyViewHolder vh = (TopicAdapter.QuickReplyViewHolder)
recyclerView.findViewHolderForAdapterPosition(viewModel.postCount());
vh.replyEditor.updateEmojiKeyboardVisibility();
}
return;
} else if (viewModel.isWritingReply()) {
topicItems.remove(topicItems.size() - 1);
@ -319,21 +307,6 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
recyclerView.scrollToPosition(position);
}
@Override
public void setEmojiKeyboardVisible(boolean visible) {
emojiKeyboard.setVisibility(visible ? View.VISIBLE : View.GONE);
}
@Override
public boolean isEmojiKeyboardVisible() {
return emojiKeyboard.getVisibility() == View.VISIBLE;
}
@Override
public void setEmojiKeyboardInputConnection(InputConnection ic) {
emojiKeyboard.setInputConnection(ic);
}
//--------------------------------------BOTTOM NAV BAR METHODS----------------------------------
/**

39
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java

@ -26,7 +26,6 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
@ -59,7 +58,7 @@ import gr.thmmy.mthmmy.activities.board.BoardActivity;
import gr.thmmy.mthmmy.activities.profile.ProfileActivity;
import gr.thmmy.mthmmy.base.BaseActivity;
import gr.thmmy.mthmmy.editorview.EditorView;
import gr.thmmy.mthmmy.editorview.EmojiKeyboard;
import gr.thmmy.mthmmy.editorview.IEmojiKeyboard;
import gr.thmmy.mthmmy.model.Poll;
import gr.thmmy.mthmmy.model.Post;
import gr.thmmy.mthmmy.model.ThmmyFile;
@ -91,7 +90,7 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static int THUMBNAIL_SIZE;
private final Context context;
private final OnPostFocusChangeListener postFocusListener;
private final EmojiKeyboard.EmojiKeyboardOwner emojiKeyboardOwner;
private final IEmojiKeyboard emojiKeyboard;
private final List<TopicItem> topicItems;
private TopicViewModel viewModel;
@ -99,11 +98,11 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
* @param context the context of the {@link RecyclerView}
* @param topicItems List of {@link Post} objects to use
*/
TopicAdapter(TopicActivity context, List<TopicItem> topicItems) {
TopicAdapter(TopicActivity context, IEmojiKeyboard emojiKeyboard, List<TopicItem> topicItems) {
this.context = context;
this.topicItems = topicItems;
this.postFocusListener = context;
this.emojiKeyboardOwner = context;
this.emojiKeyboard = emojiKeyboard;
viewModel = ViewModelProviders.of(context).get(TopicViewModel.class);
@ -590,15 +589,9 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
holder.quickReplySubject.setRawInputType(InputType.TYPE_CLASS_TEXT);
holder.quickReplySubject.setImeOptions(EditorInfo.IME_ACTION_DONE);
holder.replyEditor.setEmojiKeyboardOwner(emojiKeyboardOwner);
InputConnection ic = holder.replyEditor.getInputConnection();
emojiKeyboardOwner.setEmojiKeyboardInputConnection(ic);
holder.replyEditor.updateEmojiKeyboardVisibility();
holder.replyEditor.getEditText().setOnFocusChangeListener((v, hasFocus) -> {
InputConnection ic12 = holder.replyEditor.getInputConnection();
emojiKeyboardOwner.setEmojiKeyboardInputConnection(ic12);
holder.replyEditor.updateEmojiKeyboardVisibility();
});
holder.replyEditor.setEmojiKeyboard(emojiKeyboard);
holder.replyEditor.requestEditTextFocus();
emojiKeyboard.registerEmojiInputField(holder.replyEditor);
holder.replyEditor.setText(viewModel.getBuildedQuotes());
holder.replyEditor.setOnSubmitListener(view -> {
@ -611,7 +604,7 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
holder.itemView.setAlpha(0.5f);
holder.itemView.setEnabled(false);
emojiKeyboardOwner.setEmojiKeyboardVisible(false);
emojiKeyboard.hide();
viewModel.postReply(context, holder.quickReplySubject.getText().toString(),
holder.replyEditor.getText().toString());
@ -641,18 +634,10 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
holder.editSubject.setRawInputType(InputType.TYPE_CLASS_TEXT);
holder.editSubject.setImeOptions(EditorInfo.IME_ACTION_DONE);
holder.editEditor.setEmojiKeyboardOwner(emojiKeyboardOwner);
InputConnection ic = holder.editEditor.getInputConnection();
emojiKeyboardOwner.setEmojiKeyboardInputConnection(ic);
holder.editEditor.updateEmojiKeyboardVisibility();
holder.editEditor.setEmojiKeyboard(emojiKeyboard);
holder.editEditor.requestEditTextFocus();
emojiKeyboard.registerEmojiInputField(holder.editEditor);
holder.editEditor.setText(viewModel.getPostBeingEditedText());
holder.editEditor.getEditText().setOnFocusChangeListener((v, hasFocus) -> {
if (hasFocus) {
InputConnection ic1 = holder.editEditor.getInputConnection();
emojiKeyboardOwner.setEmojiKeyboardInputConnection(ic1);
holder.editEditor.updateEmojiKeyboardVisibility();
}
});
holder.editEditor.setOnSubmitListener(view -> {
if (holder.editSubject.getText().toString().isEmpty()) return;
if (holder.editEditor.getText().toString().isEmpty()) {
@ -663,7 +648,7 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
holder.itemView.setAlpha(0.5f);
holder.itemView.setEnabled(false);
emojiKeyboardOwner.setEmojiKeyboardVisible(false);
emojiKeyboard.hide();
viewModel.editPost(position, holder.editSubject.getText().toString(), holder.editEditor.getText().toString());
});

69
app/src/main/java/gr/thmmy/mthmmy/editorview/EditorView.java

@ -31,7 +31,7 @@ import java.util.Objects;
import gr.thmmy.mthmmy.R;
public class EditorView extends LinearLayout {
public class EditorView extends LinearLayout implements EmojiInputField {
private SparseArray<String> colors = new SparseArray<>();
@ -39,7 +39,7 @@ public class EditorView extends LinearLayout {
private TextInputEditText editText;
private AppCompatImageButton emojiButton;
private AppCompatImageButton submitButton;
private EmojiKeyboard.EmojiKeyboardOwner emojiKeyboardOwner;
private IEmojiKeyboard emojiKeyboard;
public EditorView(Context context) {
super(context);
@ -63,6 +63,22 @@ public class EditorView extends LinearLayout {
edittextWrapper = findViewById(R.id.editor_edittext_wrapper);
editText = findViewById(R.id.editor_edittext);
editText.setOnFocusChangeListener((view, focused) -> {
if (focused) emojiKeyboard.onEmojiInputFieldFocused(EditorView.this);
});
edittextWrapper.setOnFocusChangeListener((view, focused) -> {
if (focused) emojiKeyboard.onEmojiInputFieldFocused(EditorView.this);
});
editText.setOnClickListener(view -> {
if (!emojiKeyboard.isVisible()) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
} else {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getWindowToken(), 0);
requestEditTextFocus();
}
});
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.EditorView, 0, 0);
try {
@ -79,11 +95,6 @@ public class EditorView extends LinearLayout {
emojiButton = findViewById(R.id.emoji_keyboard_button);
editText.setOnTouchListener((v, event) -> {
if (emojiKeyboardOwner.isEmojiKeyboardVisible()) return true;
return false;
});
colors.append(R.id.black, "black");
colors.append(R.id.red, "red");
colors.append(R.id.yellow, "yellow");
@ -267,22 +278,28 @@ public class EditorView extends LinearLayout {
emojiButton.setOnClickListener(view -> {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
assert imm != null;
if (emojiKeyboardOwner.isEmojiKeyboardVisible()) {
//cache selection. For some reason it gets reset sometimes
int selectionStart = editText.getSelectionStart();
int selectionEnd = editText.getSelectionStart();
if (emojiKeyboard.onEmojiButtonToggle()) {
//prevent system keyboard from appearing when clicking the edittext
editText.setTextIsSelectable(true);
imm.hideSoftInputFromWindow(getWindowToken(), 0);
}
else {
editText.requestFocus();
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
emojiButton.setImageResource(R.drawable.ic_tag_faces_24dp);
} else {
imm.hideSoftInputFromWindow(getWindowToken(), 0);
view.clearFocus();
emojiButton.setImageResource(R.drawable.ic_keyboard_24dp);
}
emojiKeyboardOwner.setEmojiKeyboardVisible(!emojiKeyboardOwner.isEmojiKeyboardVisible());
editText.setSelection(selectionStart, selectionEnd);
});
submitButton = findViewById(R.id.submit_button);
}
public void setEmojiKeyboard(IEmojiKeyboard emojiKeyboard) {
this.emojiKeyboard = emojiKeyboard;
}
public TextInputEditText getEditText() {
return editText;
}
@ -307,18 +324,22 @@ public class EditorView extends LinearLayout {
submitButton.setOnClickListener(onSubmitListener);
}
public void setEmojiKeyboardOwner(EmojiKeyboard.EmojiKeyboardOwner emojiKeyboardOwner) {
this.emojiKeyboardOwner = emojiKeyboardOwner;
}
public InputConnection getInputConnection() {
return editText.onCreateInputConnection(new EditorInfo());
public boolean requestEditTextFocus() {
emojiKeyboard.onEmojiInputFieldFocused(EditorView.this);
return editText.requestFocus();
}
public void updateEmojiKeyboardVisibility() {
if (emojiKeyboardOwner.isEmojiKeyboardVisible())
@Override
public void onKeyboardVisibilityChange(boolean visible) {
if (visible) {
emojiButton.setImageResource(R.drawable.ic_keyboard_24dp);
else
} else {
emojiButton.setImageResource(R.drawable.ic_tag_faces_24dp);
}
}
@Override
public InputConnection getInputConnection() {
return editText.onCreateInputConnection(new EditorInfo());
}
}

8
app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiInputField.java

@ -0,0 +1,8 @@
package gr.thmmy.mthmmy.editorview;
import android.view.inputmethod.InputConnection;
public interface EmojiInputField {
void onKeyboardVisibilityChange(boolean visible);
InputConnection getInputConnection();
}

46
app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiKeyboard.java

@ -12,9 +12,11 @@ import android.view.MotionEvent;
import android.view.inputmethod.InputConnection;
import android.widget.LinearLayout;
import java.util.HashSet;
import gr.thmmy.mthmmy.R;
public class EmojiKeyboard extends LinearLayout {
public class EmojiKeyboard extends LinearLayout implements IEmojiKeyboard {
// TODO: Sort emojis in a way that makes sense
private final Emoji[] emojis = {new Emoji(R.drawable.emoji_smiley, ":)"),
@ -134,7 +136,9 @@ public class EmojiKeyboard extends LinearLayout {
new Emoji(R.drawable.emoji_smurf, "^smurf^")
};
InputConnection inputConnection;
private InputConnection inputConnection;
private HashSet<EmojiInputField> emojiInputFields = new HashSet<>();
private Context context;
public EmojiKeyboard(Context context) {
this(context, null, 0);
@ -150,6 +154,7 @@ public class EmojiKeyboard extends LinearLayout {
}
public void init(Context context, AttributeSet attrs) {
this.context = context;
LayoutInflater.from(context).inflate(R.layout.emoji_keyboard, this, true);
setOrientation(VERTICAL);
setBackgroundColor(getResources().getColor(R.color.primary));
@ -195,14 +200,43 @@ public class EmojiKeyboard extends LinearLayout {
});
}
@Override
public void hide() {
setVisibility(GONE);
}
@Override
public void registerEmojiInputField(EmojiInputField emojiInputField) {
emojiInputFields.add(emojiInputField);
}
public void setInputConnection(InputConnection inputConnection) {
this.inputConnection = inputConnection;
}
public interface EmojiKeyboardOwner {
void setEmojiKeyboardVisible(boolean visible);
boolean isEmojiKeyboardVisible();
void setEmojiKeyboardInputConnection(InputConnection ic);
@Override
public boolean onEmojiButtonToggle() {
if (getVisibility() == VISIBLE) setVisibility(GONE);
else setVisibility(VISIBLE);
return getVisibility() == VISIBLE;
}
@Override
public void onEmojiInputFieldFocused(EmojiInputField emojiInputField) {
setInputConnection(emojiInputField.getInputConnection());
}
@Override
public void setVisibility(int visibility) {
//notify input fields
for (EmojiInputField emojiInputField : emojiInputFields)
emojiInputField.onKeyboardVisibilityChange(visibility == VISIBLE);
super.setVisibility(visibility);
}
@Override
public boolean isVisible() {
return getVisibility() == VISIBLE;
}
class Emoji {

32
app/src/main/java/gr/thmmy/mthmmy/editorview/IEmojiKeyboard.java

@ -0,0 +1,32 @@
package gr.thmmy.mthmmy.editorview;
public interface IEmojiKeyboard {
/**
* Hide keyboard
*/
void hide();
/**
* Check if keyboard is visible
* @return true, if {@link EmojiKeyboard#getVisibility()} returns View.VISIBLE, otherwise false
*/
boolean isVisible();
/**
* Callback to the keyboard when {@link EditorView#emojiButton} is clicked
* @return whether the keyboard became visible or not
*/
boolean onEmojiButtonToggle();
/**
* Callback to create input connection with {@link EmojiInputField}
* @param emojiInputField the connected input field
*/
void onEmojiInputFieldFocused(EmojiInputField emojiInputField);
/**
* Persist a set of all input fields to update all of them when visibility changes
* @param emojiInputField the input field to be added
*/
void registerEmojiInputField(EmojiInputField emojiInputField);
}
Loading…
Cancel
Save