Browse Source

Copy links from WebViews on long clicks

pull/70/head
Ezerous 5 years ago
parent
commit
ca2432d904
No known key found for this signature in database GPG Key ID: 262B2954BBA319E3
  1. 6
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java
  2. 5
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
  3. 78
      app/src/main/java/gr/thmmy/mthmmy/utils/ui/WebViewOnTouchClickListener.java
  4. 105
      app/src/main/java/gr/thmmy/mthmmy/views/ReactiveWebView.java
  5. 2
      app/src/main/res/layout-v21/activity_topic_post_row.xml
  6. 2
      app/src/main/res/layout/activity_topic_post_row.xml
  7. 2
      app/src/main/res/layout/fragment_latest_posts_row.xml

6
app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java

@ -6,7 +6,6 @@ import android.graphics.Color;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
@ -18,7 +17,7 @@ import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseFragment; import gr.thmmy.mthmmy.base.BaseFragment;
import gr.thmmy.mthmmy.model.PostSummary; import gr.thmmy.mthmmy.model.PostSummary;
import gr.thmmy.mthmmy.model.TopicSummary; import gr.thmmy.mthmmy.model.TopicSummary;
import gr.thmmy.mthmmy.utils.ui.WebViewOnTouchClickListener; import gr.thmmy.mthmmy.views.ReactiveWebView;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar; import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
/** /**
@ -81,7 +80,6 @@ class LatestPostsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
latestPostViewHolder.post.setBackgroundColor(Color.argb(1, 255, 255, 255)); latestPostViewHolder.post.setBackgroundColor(Color.argb(1, 255, 255, 255));
latestPostViewHolder.post.loadDataWithBaseURL("file:///android_asset/" latestPostViewHolder.post.loadDataWithBaseURL("file:///android_asset/"
, topic.getPost(), "text/html", "UTF-8", null); , topic.getPost(), "text/html", "UTF-8", null);
latestPostViewHolder.post.setOnTouchListener(new WebViewOnTouchClickListener(context));
latestPostViewHolder.latestPostsRow.setOnClickListener(v -> { latestPostViewHolder.latestPostsRow.setOnClickListener(v -> {
if (interactionListener != null) { if (interactionListener != null) {
@ -106,7 +104,7 @@ class LatestPostsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
final RelativeLayout latestPostsRow; final RelativeLayout latestPostsRow;
final TextView postTitle; final TextView postTitle;
final TextView postDate; final TextView postDate;
final WebView post; final ReactiveWebView post;
LatestPostViewHolder(View itemView) { LatestPostViewHolder(View itemView) {
super(itemView); super(itemView);

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

@ -73,8 +73,8 @@ import gr.thmmy.mthmmy.model.TopicItem;
import gr.thmmy.mthmmy.utils.parsing.ParseHelpers; import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
import gr.thmmy.mthmmy.utils.parsing.ThmmyParser; import gr.thmmy.mthmmy.utils.parsing.ThmmyParser;
import gr.thmmy.mthmmy.utils.ui.CircleTransform; import gr.thmmy.mthmmy.utils.ui.CircleTransform;
import gr.thmmy.mthmmy.utils.ui.WebViewOnTouchClickListener;
import gr.thmmy.mthmmy.viewmodel.TopicViewModel; import gr.thmmy.mthmmy.viewmodel.TopicViewModel;
import gr.thmmy.mthmmy.views.ReactiveWebView;
import gr.thmmy.mthmmy.views.editorview.EditorView; import gr.thmmy.mthmmy.views.editorview.EditorView;
import gr.thmmy.mthmmy.views.editorview.IEmojiKeyboard; import gr.thmmy.mthmmy.views.editorview.IEmojiKeyboard;
import timber.log.Timber; import timber.log.Timber;
@ -363,7 +363,6 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
//Post's WebView parameters //Post's WebView parameters
holder.post.setClickable(true); holder.post.setClickable(true);
holder.post.setWebViewClient(new LinkLauncher()); holder.post.setWebViewClient(new LinkLauncher());
holder.post.setOnTouchListener(new WebViewOnTouchClickListener(context));
//noinspection ConstantConditions //noinspection ConstantConditions
loadAvatar(currentPost.getThumbnailURL(), holder.thumbnail); loadAvatar(currentPost.getThumbnailURL(), holder.thumbnail);
@ -834,7 +833,7 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
final LinearLayout cardChildLinear; final LinearLayout cardChildLinear;
final TextView postDate, postNum, username, subject; final TextView postDate, postNum, username, subject;
final ImageView thumbnail; final ImageView thumbnail;
final public WebView post; final public ReactiveWebView post;
final ImageButton quoteToggle, overflowButton; final ImageButton quoteToggle, overflowButton;
final RelativeLayout header; final RelativeLayout header;
final LinearLayout userExtraInfo; final LinearLayout userExtraInfo;

78
app/src/main/java/gr/thmmy/mthmmy/utils/ui/WebViewOnTouchClickListener.java

@ -1,78 +0,0 @@
package gr.thmmy.mthmmy.utils.ui;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.webkit.WebView;
import com.bumptech.glide.Glide;
import com.github.chrisbanes.photoview.PhotoView;
import gr.thmmy.mthmmy.base.BaseApplication;
/**
* Workaround for WebView's inability to send onClick events (sends only onLongClickEvents)
* If an image is find when clicking it will be inflated as a zoomed/zoomable/pinchable PhotoView
*/
public class WebViewOnTouchClickListener implements View.OnTouchListener {
private final static int screenWidth = BaseApplication.getInstance().getWidthInPixels();
private final static int screenHeight = BaseApplication.getInstance().getHeightInPixels();
private final static long MAX_TOUCH_DURATION = 100;
private final Context context;
private long downTime;
public WebViewOnTouchClickListener(Context context){
this.context = context;
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downTime = event.getEventTime();
break;
case MotionEvent.ACTION_UP:
if(event.getEventTime() - downTime <= MAX_TOUCH_DURATION)
onClick((WebView) v);
break;
default:
break;
}
return false;
}
private void onClick(WebView webView){
WebView.HitTestResult result = webView.getHitTestResult();
if(result.getType() == WebView.HitTestResult.IMAGE_TYPE){
String imageURL = result.getExtra();
showImage(imageURL);
}
webView.performClick();
}
private void showImage(String url) {
Dialog builder = new Dialog(context);
builder.requestWindowFeature(Window.FEATURE_NO_TITLE);
builder.getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
builder.getWindow().setBackgroundDrawable(
new ColorDrawable(android.graphics.Color.TRANSPARENT));
PhotoView photoView = new PhotoView(context);
photoView.setLayoutParams(new LayoutParams(screenWidth, screenHeight));
Glide.with(context).load(url).fitCenter().into(photoView);
builder.addContentView(photoView, new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
builder.show();
}
}

105
app/src/main/java/gr/thmmy/mthmmy/views/ReactiveWebView.java

@ -0,0 +1,105 @@
package gr.thmmy.mthmmy.views;
import android.app.Dialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.WebView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.github.chrisbanes.photoview.PhotoView;
import gr.thmmy.mthmmy.base.BaseApplication;
import static android.content.Context.CLIPBOARD_SERVICE;
public class ReactiveWebView extends WebView {
private final static int screenWidth = BaseApplication.getInstance().getWidthInPixels();
private final static int screenHeight = BaseApplication.getInstance().getHeightInPixels();
private final static long MAX_TOUCH_DURATION = 100;
private final Context context;
private long downTime;
public ReactiveWebView(Context context) {
super(context);
this.context = context;
setOnLongClickListener();
}
public ReactiveWebView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
setOnLongClickListener();
}
public ReactiveWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
setOnLongClickListener();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downTime = event.getEventTime();
break;
case MotionEvent.ACTION_UP:
if(event.getEventTime() - downTime <= MAX_TOUCH_DURATION)
performClick();
break;
default:
break;
}
return super.onTouchEvent(event);
}
@Override
public boolean performClick() {
WebView.HitTestResult result = this.getHitTestResult();
if(result.getType() == WebView.HitTestResult.IMAGE_TYPE){
String imageURL = result.getExtra();
showImage(imageURL);
}
return super.performClick();
}
private void showImage(String url) {
Dialog builder = new Dialog(context);
builder.requestWindowFeature(Window.FEATURE_NO_TITLE);
builder.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
builder.getWindow().setBackgroundDrawable(
new ColorDrawable(android.graphics.Color.TRANSPARENT));
PhotoView photoView = new PhotoView(context);
photoView.setLayoutParams(new ViewGroup.LayoutParams(screenWidth, screenHeight));
Glide.with(context).load(url).fitCenter().into(photoView);
builder.addContentView(photoView, new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
builder.show();
}
private void setOnLongClickListener(){
this.setOnLongClickListener(v -> {
HitTestResult result = ReactiveWebView.this.getHitTestResult();
if(result.getType() == HitTestResult.SRC_ANCHOR_TYPE){
ClipboardManager clipboard = (ClipboardManager) BaseApplication.getInstance().getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("ReactiveWebViewCopiedText", result.getExtra());
clipboard.setPrimaryClip(clip);
Toast.makeText(BaseApplication.getInstance().getApplicationContext(),"Link copied",Toast.LENGTH_SHORT).show();
}
return false;
});
}
}

2
app/src/main/res/layout-v21/activity_topic_post_row.xml

@ -225,7 +225,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginBottom="16dp"> android:layout_marginBottom="16dp">
<WebView <gr.thmmy.mthmmy.views.ReactiveWebView
android:id="@+id/post" android:id="@+id/post"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

2
app/src/main/res/layout/activity_topic_post_row.xml

@ -225,7 +225,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginBottom="16dp"> android:layout_marginBottom="16dp">
<WebView <gr.thmmy.mthmmy.views.ReactiveWebView
android:id="@+id/post" android:id="@+id/post"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

2
app/src/main/res/layout/fragment_latest_posts_row.xml

@ -50,7 +50,7 @@
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_below="@+id/spacer_divider"> android:layout_below="@+id/spacer_divider">
<WebView <gr.thmmy.mthmmy.views.ReactiveWebView
android:id="@+id/post" android:id="@+id/post"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

Loading…
Cancel
Save