From 66adbd5b6b90b6a639a08787b300c95630693e88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8C=96=E5=8D=81?= Date: Tue, 21 Aug 2018 17:50:16 +0800 Subject: [PATCH] fix dialogfragment to popupwindow --- .../hurshi/clickedwords/MainActivity.java | 53 ++++- .../hurshi/clickedwords/WordDetailDialog.java | 25 --- app/src/main/res/drawable/popup_window_bg.xml | 18 ++ app/src/main/res/layout/activity_main.xml | 1 + app/src/main/res/layout/view_words.xml | 8 +- .../hurshi/clickedwordslib/ClickedWords.java | 205 ------------------ .../OnWordsClickedListener.java | 5 - .../clickedwordslib/WordDetailDialog.java | 161 -------------- .../clickedwordslib/WordsDetailLayout.java | 10 - .../clickedwordslib/core/ClickedWords.java | 156 +++++++++++++ .../core/OnWordsClickedListener.java | 9 + .../helper/ClickedWordsDisplayer.java | 67 ++++++ .../ui/OnWordsDisplayListener.java | 10 + .../clickedwordslib/util/ClickWordsUtils.java | 19 ++ .../src/main/res/anim/slide_bottom_in.xml | 7 - .../src/main/res/anim/slide_bottom_out.xml | 7 - .../src/main/res/values/styles.xml | 17 -- 17 files changed, 326 insertions(+), 452 deletions(-) delete mode 100644 app/src/main/java/com/github/hurshi/clickedwords/WordDetailDialog.java create mode 100644 app/src/main/res/drawable/popup_window_bg.xml delete mode 100644 clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/ClickedWords.java delete mode 100644 clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/OnWordsClickedListener.java delete mode 100644 clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/WordDetailDialog.java delete mode 100644 clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/WordsDetailLayout.java create mode 100644 clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/core/ClickedWords.java create mode 100644 clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/core/OnWordsClickedListener.java create mode 100644 clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/helper/ClickedWordsDisplayer.java create mode 100644 clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/ui/OnWordsDisplayListener.java create mode 100644 clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/util/ClickWordsUtils.java delete mode 100644 clickedwordslib/src/main/res/anim/slide_bottom_in.xml delete mode 100644 clickedwordslib/src/main/res/anim/slide_bottom_out.xml delete mode 100644 clickedwordslib/src/main/res/values/styles.xml diff --git a/app/src/main/java/com/github/hurshi/clickedwords/MainActivity.java b/app/src/main/java/com/github/hurshi/clickedwords/MainActivity.java index 4c67134..d0660c7 100644 --- a/app/src/main/java/com/github/hurshi/clickedwords/MainActivity.java +++ b/app/src/main/java/com/github/hurshi/clickedwords/MainActivity.java @@ -1,19 +1,29 @@ package com.github.hurshi.clickedwords; +import android.os.Build; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.text.SpannableString; import android.text.style.BackgroundColorSpan; import android.text.style.ForegroundColorSpan; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.PopupWindow; import android.widget.TextView; -import com.github.hurshi.clickedwordslib.ClickedWords; +import com.github.hurshi.clickedwordslib.core.ClickedWords; +import com.github.hurshi.clickedwordslib.helper.ClickedWordsDisplayer; +import com.github.hurshi.clickedwordslib.ui.OnWordsDisplayListener; -public class MainActivity extends AppCompatActivity { +public class MainActivity extends AppCompatActivity implements OnWordsDisplayListener { private TextView textView1; private TextView textView2; private TextView textView3; - WordDetailDialog wordDetailDialog = new WordDetailDialog(); + + private PopupWindow popupWindow; + private TextView tv; @Override @@ -25,10 +35,19 @@ protected void onCreate(Bundle savedInstanceState) { textView3 = (TextView) findViewById(R.id.textview3); setTextViewSpanStr(); + + LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); + View popupView = inflater.inflate(R.layout.view_words, null); + tv = (TextView) popupView.findViewById(R.id.textview); + + popupWindow = new PopupWindow(popupView, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, true); + + if (Build.VERSION.SDK_INT >= 21) + popupWindow.setElevation(20); + setClickedWords(textView1); setClickedWords(textView2); setClickedWords(textView3); - } private void setTextViewSpanStr() { @@ -38,13 +57,25 @@ private void setTextViewSpanStr() { textView2.setText(spannableString); } + @Override + public void wordDisplay(String words) { + tv.setText(words); + } + + @Override + public void showPopupWindow(PopupWindow popupWindow, TextView textView, int offsetX, int offsetY) { + popupWindow.showAtLocation(textView, Gravity.CENTER_HORIZONTAL | Gravity.TOP, offsetX, offsetY); + } + private void setClickedWords(TextView textView) { - new ClickedWords.Builder() - .setTextView(textView) - .setWordDetailDialog(wordDetailDialog) - .setFragmentManager(getSupportFragmentManager()) - .setFocusedBgColor(R.color.focusedBgColor) - .setFocusedFgColor(R.color.focusedFgColor) - .build(); + ClickedWordsDisplayer.showAsPopupWindow( + new ClickedWords.Builder() + .setTextView(textView), + popupWindow, + this, + R.color.focusedFgColor, + R.color.focusedBgColor + ); } + } diff --git a/app/src/main/java/com/github/hurshi/clickedwords/WordDetailDialog.java b/app/src/main/java/com/github/hurshi/clickedwords/WordDetailDialog.java deleted file mode 100644 index 2afa5cb..0000000 --- a/app/src/main/java/com/github/hurshi/clickedwords/WordDetailDialog.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.github.hurshi.clickedwords; - -import android.view.View; -import android.widget.TextView; - -public class WordDetailDialog extends com.github.hurshi.clickedwordslib.WordDetailDialog { - public WordDetailDialog() { - } - - @Override - public int getLayoutRes() { - return R.layout.view_words; - } - - @Override - public void setUpView(View v, String word) { -// Toast.makeText(getContext(), word, Toast.LENGTH_SHORT).show(); - ((TextView) (v.findViewById(R.id.textview))).setText(word); - } - - @Override - public String getFragmentTag() { - return "WordDetailDialog"; - } -} diff --git a/app/src/main/res/drawable/popup_window_bg.xml b/app/src/main/res/drawable/popup_window_bg.xml new file mode 100644 index 0000000..d6aea98 --- /dev/null +++ b/app/src/main/res/drawable/popup_window_bg.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index d5ecb0e..aec51ed 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -25,6 +25,7 @@ android:id="@+id/textview2" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginLeft="100dp" android:layout_marginTop="40dp" android:text="At Monday night's announcement in the East Room, Judge Kavanaugh, 53, said: Mr President, thank you. Throughout this process I have witnessed firsthand your appreciation for the vital role of the American judiciary." android:textSize="20sp" /> diff --git a/app/src/main/res/layout/view_words.xml b/app/src/main/res/layout/view_words.xml index 2d2968d..ad00cb2 100644 --- a/app/src/main/res/layout/view_words.xml +++ b/app/src/main/res/layout/view_words.xml @@ -1,14 +1,14 @@ + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="@drawable/popup_window_bg"> 0) { - for (TextView tv : builder.getTextViews()) { - if (null != tv) - toBuild(builder, tv); - } - } - } - - private void toBuild(final Builder builder, final TextView textView) { - textView.setOnTouchListener(new View.OnTouchListener() { - float downX = 0; - float downY = 0; - - @Override - public boolean onTouch(View view, MotionEvent motionEvent) { - if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { - downX = motionEvent.getX(); - downY = motionEvent.getY(); - } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) { - if (Math.abs(downX - motionEvent.getX()) + Math.abs(downY - motionEvent.getY()) < 25) { - int offset = textView.getOffsetForPosition(motionEvent.getX(), motionEvent.getY()); - Pair positions = getWord(textView.getText().toString(), offset); - if (positions.first >= 0 && positions.first <= textView.getText().length() && positions.second >= 0 && positions.second <= textView.getText().length()) { - String words = textView.getText().toString().substring(positions.first, positions.second); - if (null != builder.getListener()) { - builder.getListener().wordsClicked(words); - } - if (null != builder.getWordDetailDialog()) { - showWordDetail(builder, textView, positions, words); - } - } - } - } - return true; - } - }); - } - - private Pair getWord(String string, int offset) { - BreakIterator breakIterator = getWordIterator(); - breakIterator.setText(string); - - int start = breakIterator.first(); - int end = breakIterator.next(); - while (end != BreakIterator.DONE) { - if (offset >= start && offset <= end) { - break; - } - start = end; - end = breakIterator.next(); - } - return new Pair<>(start, end); - } - - private void showWordDetail(final Builder builder, final TextView textView, Pair positions, String words) { - builder.getWordDetailDialog().clear(); - if (null == words) { - return; - } - if (builder.getWordDetailDialog().setWords(words)) { - final CharSequence spannableTxt = textView.getText(); - setTextViewClicked(builder, textView, positions); - builder.getWordDetailDialog().setListener(new WordDetailDialog.OnBottomDialogDismissListener() { - @Override - public void onDismiss() { - setTextViewNormal(textView, spannableTxt); - builder.getWordDetailDialog().hide(builder.getFragmentManager()); - } - }); - builder.getWordDetailDialog().show(builder.getFragmentManager()); - } - } - - private void setTextViewClicked(Builder builder, TextView textView, Pair positions) { - SpannableString spannableString = new SpannableString(textView.getText()); - int fgColor = builder.getFocusedFgColor(); - if (fgColor > 0) { - spannableString.setSpan(new ForegroundColorSpan(textView.getContext().getResources().getColor(fgColor)), positions.first, positions.second, Spanned.SPAN_EXCLUSIVE_INCLUSIVE); - } - int bgColor = builder.getFocusedBgColor(); - if (bgColor > 0) { - spannableString.setSpan(new BackgroundColorSpan(textView.getContext().getResources().getColor(bgColor)), positions.first, positions.second, Spanned.SPAN_EXCLUSIVE_INCLUSIVE); - } - textView.setText(spannableString); - } - - private void setTextViewNormal(TextView textView, CharSequence txt) { - textView.setText(txt); - } - - public static class Builder { - private FragmentManager fragmentManager; - private TextView textView; - private OnWordsClickedListener listener; - private WordDetailDialog wordDetailDialog; - private int focusedBgColor; - private int focusedFgColor; - private TextView[] textViews; - - private FragmentManager getFragmentManager() { - return fragmentManager; - } - - public Builder setFragmentManager(FragmentManager fragmentManager) { - this.fragmentManager = fragmentManager; - return this; - } - - private TextView getTextView() { - return textView; - } - - public Builder setTextView(TextView textView) { - this.textView = textView; - return this; - } - - private OnWordsClickedListener getListener() { - return listener; - } - - public Builder setListener(OnWordsClickedListener listener) { - this.listener = listener; - return this; - } - - private WordDetailDialog getWordDetailDialog() { - return wordDetailDialog; - } - - public Builder setWordDetailDialog(WordDetailDialog wordDetailDialog) { - this.wordDetailDialog = wordDetailDialog; - return this; - } - - private int getFocusedBgColor() { - return focusedBgColor; - } - - public Builder setFocusedBgColor(int focusedBgColor) { - this.focusedBgColor = focusedBgColor; - return this; - } - - private int getFocusedFgColor() { - return focusedFgColor; - } - - public Builder setFocusedFgColor(int focusedFgColor) { - this.focusedFgColor = focusedFgColor; - return this; - } - - private TextView[] getTextViews() { - return textViews; - } - - public Builder setTextViews(TextView[] textViews) { - this.textViews = textViews; - return this; - } - - public ClickedWords build() { - if (null == textView && (null == textViews || textViews.length <= 0)) { - throw new IllegalArgumentException("TextView or TextView array can not be null"); - } - if (null == fragmentManager && null == wordDetailDialog) { - throw new IllegalArgumentException("WordDetailDialog need FragmentManager not be null"); - } - return new ClickedWords(this); - - } - } - - -} diff --git a/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/OnWordsClickedListener.java b/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/OnWordsClickedListener.java deleted file mode 100644 index a14948b..0000000 --- a/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/OnWordsClickedListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.hurshi.clickedwordslib; - -public interface OnWordsClickedListener { - void wordsClicked(String words); -} diff --git a/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/WordDetailDialog.java b/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/WordDetailDialog.java deleted file mode 100644 index 228e3bd..0000000 --- a/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/WordDetailDialog.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.github.hurshi.clickedwordslib; - -import android.content.DialogInterface; -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.v4.app.DialogFragment; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentTransaction; -import android.support.v7.app.AppCompatDialogFragment; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.Window; -import android.view.WindowManager; - -import io.reactivex.Observable; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.Disposable; -import io.reactivex.functions.Consumer; -import io.reactivex.schedulers.Schedulers; - -public abstract class WordDetailDialog extends AppCompatDialogFragment { - private OnBottomDialogDismissListener listener; - private String words; - - public WordDetailDialog() { - } - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setStyle(DialogFragment.STYLE_NO_TITLE, R.style.BottomDialog); - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); - getDialog().setCanceledOnTouchOutside(true); - return inflater.inflate(getLayoutRes(), container, false); - } - - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - Window window = getDialog().getWindow(); - window.setAttributes(getDialogLayoutParams(window.getAttributes())); - - getDialog().setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialogInterface) { - clear(); - } - }); - setUpView(getView(), words); - } - - - public void setListener(OnBottomDialogDismissListener listener) { - this.listener = listener; - } - - private Disposable disposable; - - public boolean setWords(String w) { - this.words = w; - if (null != getView()) { - if (null != disposable && !disposable.isDisposed()) { - disposable.dispose(); - if (null != listener) { - listener.onDismiss(); - } - } - disposable = Observable.just(words) - .subscribeOn(Schedulers.newThread()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Consumer() { - @Override - public void accept(String string) throws Exception { - setUpView(getView(), words); - disposable = null; - } - }); - } - return true; - } - - public void show(FragmentManager manager) { - show(manager, getFragmentTag()); - } - - @Override - public void show(FragmentManager manager, String tag) { - if (null == manager) { - return; - } - Fragment fragment = manager.findFragmentByTag(tag); - FragmentTransaction ft = manager.beginTransaction(); - if (null == fragment) { - ft.add(this, tag); - } else { - ft.show(this); - getDialog().show(); - } - ft.commitAllowingStateLoss(); - } - - public void hide(FragmentManager manager) { - if (null == manager) { - return; - } - FragmentTransaction ft = manager.beginTransaction(); - ft.hide(this); - ft.commitAllowingStateLoss(); - } - - public abstract int getLayoutRes(); - - public abstract String getFragmentTag(); - - public abstract void setUpView(View v, String word); - - protected void onDialogDismiss() { - - } - - public void clear() { - if (null != getActivity() && !getActivity().isFinishing()) { - onDialogDismiss(); - if (null != listener) { - listener.onDismiss(); - } - } - if (null != disposable && !disposable.isDisposed()) { - disposable.dispose(); - } - - listener = null; - words = ""; - } - - @Override - public void onSaveInstanceState(Bundle outState) { - - } - - protected WindowManager.LayoutParams getDialogLayoutParams(WindowManager.LayoutParams params) { - params.width = WindowManager.LayoutParams.MATCH_PARENT; - params.height = WindowManager.LayoutParams.WRAP_CONTENT; - params.gravity = Gravity.BOTTOM; - return params; - } - - public interface OnBottomDialogDismissListener { - void onDismiss(); - } -} diff --git a/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/WordsDetailLayout.java b/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/WordsDetailLayout.java deleted file mode 100644 index 1cc1bbc..0000000 --- a/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/WordsDetailLayout.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.github.hurshi.clickedwordslib; - -import android.view.View; - -public interface WordsDetailLayout { - int getLayoutResId(); - - void setupView(View view, String word); - -} diff --git a/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/core/ClickedWords.java b/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/core/ClickedWords.java new file mode 100644 index 0000000..d1aa374 --- /dev/null +++ b/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/core/ClickedWords.java @@ -0,0 +1,156 @@ +package com.github.hurshi.clickedwordslib.core; + +import android.graphics.Rect; +import android.support.v4.util.Pair; +import android.view.MotionEvent; +import android.view.View; +import android.widget.TextView; + +import java.text.BreakIterator; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +public class ClickedWords { + private BreakIterator wordIterator; + + private BreakIterator getWordIterator() { + if (null == wordIterator) { + wordIterator = BreakIterator.getWordInstance(Locale.US); + } + return wordIterator; + } + + ClickedWords(final Builder builder) { + if (null != builder.getTextView()) { + toBuild(builder, builder.getTextView()); + } + if (null != builder.getTextViews() && builder.getTextViews().length > 0) { + for (TextView tv : builder.getTextViews()) { + if (null != tv) + toBuild(builder, tv); + } + } + } + + private void toBuild(final Builder builder, final TextView textView) { + textView.setOnTouchListener(new View.OnTouchListener() { + float downX = 0; + float downY = 0; + + @Override + public boolean onTouch(View view, MotionEvent motionEvent) { + if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { + downX = motionEvent.getX(); + downY = motionEvent.getY(); + } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) { + if (Math.abs(downX - motionEvent.getX()) + Math.abs(downY - motionEvent.getY()) < 25) { + int offset = textView.getOffsetForPosition(motionEvent.getX(), motionEvent.getY()); + Pair indexs = getWord(textView.getText().toString(), offset); + if (indexs.first >= 0 && indexs.first <= textView.getText().length() && indexs.second >= 0 && indexs.second <= textView.getText().length()) { + String words = textView.getText().toString().substring(indexs.first, indexs.second); + if (null != builder.getListeners() && builder.getListeners().size() > 0) { + int[] outLocation = new int[2]; + textView.getLocationOnScreen(outLocation); + Rect r = getSelectedTxtRect(textView, indexs); + for (OnWordsClickedListener l : builder.getListeners()) { + if (null != l) { + l.wordsClicked(textView, words, indexs, r, outLocation); + } + } + } + } + } + } + return true; + } + }); + } + + private Rect getSelectedTxtRect(TextView textView, Pair indexs) { + Rect r = new Rect(); + if (null != indexs && null != indexs.first && null != indexs.second) { + int lineStart = textView.getLayout().getLineForOffset(indexs.first); + int lineEnd = textView.getLayout().getLineForOffset(indexs.second); + r.top = textView.getLayout().getLineTop(lineStart); + r.bottom = textView.getLayout().getLineBottom(lineEnd); + r.left = (int) textView.getLayout().getPrimaryHorizontal(indexs.first); + r.right = (int) textView.getLayout().getPrimaryHorizontal(indexs.second); + + int paddingLeft = textView.getCompoundPaddingLeft(); + int paddingTop = textView.getExtendedPaddingTop(); +// if ((textView.getGravity() & Gravity.VERTICAL_GRAVITY_MASK) != Gravity.TOP) { +// paddingTop += textView.getVerticalOffset(false); +// } + r.offset(paddingLeft, paddingTop); + int paddingBottom = textView.getExtendedPaddingBottom(); + r.bottom += paddingBottom; + } + return r; + } + + private Pair getWord(String string, int offset) { + BreakIterator breakIterator = getWordIterator(); + breakIterator.setText(string); + + int start = breakIterator.first(); + int end = breakIterator.next(); + while (end != BreakIterator.DONE) { + if (offset >= start && offset <= end) { + break; + } + start = end; + end = breakIterator.next(); + } + return new Pair<>(start, end); + } + + public static class Builder { + private TextView textView; + private List listeners; + private TextView[] textViews; + + + public TextView getTextView() { + return textView; + } + + public Builder setTextView(TextView textView) { + this.textView = textView; + return this; + } + + public List getListeners() { + return listeners; + } + + public Builder addListener(OnWordsClickedListener listener) { + if (null == listeners) { + listeners = new ArrayList<>(); + } + if (null != listener && !listeners.contains(listener)) { + listeners.add(listener); + } + return this; + } + + public TextView[] getTextViews() { + return textViews; + } + + public Builder setTextViews(TextView[] textViews) { + this.textViews = textViews; + return this; + } + + public ClickedWords build() { + if (null == textView && (null == textViews || textViews.length <= 0)) { + throw new IllegalArgumentException("TextView or TextView array can not be null"); + } + return new ClickedWords(this); + + } + } + + +} diff --git a/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/core/OnWordsClickedListener.java b/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/core/OnWordsClickedListener.java new file mode 100644 index 0000000..1ffa34c --- /dev/null +++ b/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/core/OnWordsClickedListener.java @@ -0,0 +1,9 @@ +package com.github.hurshi.clickedwordslib.core; + +import android.graphics.Rect; +import android.support.v4.util.Pair; +import android.widget.TextView; + +public interface OnWordsClickedListener { + void wordsClicked(TextView textView, String words, Pair index, Rect focusedRect, int[] locationInScreen); +} diff --git a/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/helper/ClickedWordsDisplayer.java b/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/helper/ClickedWordsDisplayer.java new file mode 100644 index 0000000..c4caacf --- /dev/null +++ b/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/helper/ClickedWordsDisplayer.java @@ -0,0 +1,67 @@ +package com.github.hurshi.clickedwordslib.helper; + +import android.graphics.Rect; +import android.support.v4.util.Pair; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.style.BackgroundColorSpan; +import android.text.style.ForegroundColorSpan; +import android.widget.PopupWindow; +import android.widget.TextView; + +import com.github.hurshi.clickedwordslib.core.ClickedWords; +import com.github.hurshi.clickedwordslib.core.OnWordsClickedListener; +import com.github.hurshi.clickedwordslib.ui.OnWordsDisplayListener; +import com.github.hurshi.clickedwordslib.util.ClickWordsUtils; + +public class ClickedWordsDisplayer { + public static void showAsPopupWindow(ClickedWords.Builder builder, final PopupWindow popupWindow, final OnWordsDisplayListener listener, final int focusedFgColor, final int focusedBgColor) { + if (null == popupWindow) { + return; + } + builder.addListener(new OnWordsClickedListener() { + @Override + public void wordsClicked(TextView textView, String words, Pair index, Rect focusedRect, int[] locationInScreen) { + int x = (int) (locationInScreen[0] + focusedRect.left + (focusedRect.right - focusedRect.left - ClickWordsUtils.getScreenW(textView.getContext())) / 2.0f); + int y = locationInScreen[1] + focusedRect.bottom; + setClickedStyle(textView, popupWindow, index, focusedFgColor, focusedBgColor); + if (null != listener) { + listener.wordDisplay(words); + listener.showPopupWindow(popupWindow, textView, x, y); + } + } + }); + builder.build(); + } + + private static void setClickedStyle(final TextView textView, final PopupWindow popupWindow, Pair indexs, int focusedFgColor, int focusedBgColor) { + final CharSequence spannableTxt = textView.getText(); + setTextViewClicked(textView, indexs, focusedFgColor, focusedBgColor); + popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { + @Override + public void onDismiss() { + popupWindow.setOnDismissListener(null); + setTextViewNormal(textView, spannableTxt); + } + }); + } + + private static void setTextViewClicked(TextView textView, Pair indexs, int focusedFgColor, int focusedBgColor) { + if (null == indexs || null == indexs.first || null == indexs.second) { + return; + } + SpannableString spannableString = new SpannableString(textView.getText()); + if (focusedFgColor > 0) { + spannableString.setSpan(new ForegroundColorSpan(textView.getContext().getResources().getColor(focusedFgColor)), indexs.first, indexs.second, Spanned.SPAN_EXCLUSIVE_INCLUSIVE); + } + if (focusedBgColor > 0) { + spannableString.setSpan(new BackgroundColorSpan(textView.getContext().getResources().getColor(focusedBgColor)), indexs.first, indexs.second, Spanned.SPAN_EXCLUSIVE_INCLUSIVE); + } + textView.setText(spannableString); + } + + private static void setTextViewNormal(TextView textView, CharSequence txt) { + textView.setText(txt); + } + +} diff --git a/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/ui/OnWordsDisplayListener.java b/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/ui/OnWordsDisplayListener.java new file mode 100644 index 0000000..1211d2a --- /dev/null +++ b/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/ui/OnWordsDisplayListener.java @@ -0,0 +1,10 @@ +package com.github.hurshi.clickedwordslib.ui; + +import android.widget.PopupWindow; +import android.widget.TextView; + +public interface OnWordsDisplayListener { + void wordDisplay(String words); + + void showPopupWindow(PopupWindow popupWindow, TextView textView, int offsetX, int offsetY); +} diff --git a/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/util/ClickWordsUtils.java b/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/util/ClickWordsUtils.java new file mode 100644 index 0000000..c775351 --- /dev/null +++ b/clickedwordslib/src/main/java/com/github/hurshi/clickedwordslib/util/ClickWordsUtils.java @@ -0,0 +1,19 @@ +package com.github.hurshi.clickedwordslib.util; + +import android.content.Context; + +public class ClickWordsUtils { + /** + * 获取屏幕宽度 + */ + public static int getScreenW(Context aty) { + return aty.getResources().getDisplayMetrics().widthPixels; + } + + /** + * 获取屏幕高度 + */ + public static int getScreenH(Context aty) { + return aty.getResources().getDisplayMetrics().heightPixels; + } +} diff --git a/clickedwordslib/src/main/res/anim/slide_bottom_in.xml b/clickedwordslib/src/main/res/anim/slide_bottom_in.xml deleted file mode 100644 index 5c7dbbc..0000000 --- a/clickedwordslib/src/main/res/anim/slide_bottom_in.xml +++ /dev/null @@ -1,7 +0,0 @@ - - \ No newline at end of file diff --git a/clickedwordslib/src/main/res/anim/slide_bottom_out.xml b/clickedwordslib/src/main/res/anim/slide_bottom_out.xml deleted file mode 100644 index d16a8d5..0000000 --- a/clickedwordslib/src/main/res/anim/slide_bottom_out.xml +++ /dev/null @@ -1,7 +0,0 @@ - - diff --git a/clickedwordslib/src/main/res/values/styles.xml b/clickedwordslib/src/main/res/values/styles.xml deleted file mode 100644 index 23699b8..0000000 --- a/clickedwordslib/src/main/res/values/styles.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - -