Android EditText销毁Webview Actionmode

时间:2017-05-19 08:00:44

标签: java android webview android-edittext

背景:

  • 我有一个带有actionmode回调的webview。

  • 如果您在webview上长按并进行文本选择,则会显示动作模式。

  • webview actionmode的编辑菜单选项会在webview底部打开一个包含编辑文本字段的linearlayout。

问题:

  • 单击edittext字段后, actionmode将关闭 (线性布局上还有一个按钮,它不会像编辑文本那样关闭动作模式)

预期结果:

  • 即使用户点击并输入了修改文字
  • ,我希望选择保持选中状态

更多信息:

  • 在API 21上测试 - andriod 5.0点击编辑文本每次关闭动作模式,但是在API 25中 - android 7.1.1 点击编辑文本第一次关闭动作模式,单击编辑文本第二次不关闭动作模式,按预期工作从此处开始。

代码:

您可以在此处从github克隆项目: https://github.com/fmarais/webview_edit_text/tree/master

应用/ SRC /主/ JAVA / COM / my_package / webview_edit_text / MainActivity.java

package com.my_package.webview_edit_text;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.ActionMode;
import android.view.View;
import android.webkit.WebViewClient;
import android.widget.EditText;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {
    private CustomWebview mWebview;
    private ActionMode mActionMode;
    private LinearLayout editLayout;
    private EditText editText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getSupportActionBar().setTitle("onCreate()");

        editLayout = (LinearLayout) findViewById(R.id.edit_layout);
        editText = (EditText) findViewById(R.id.edit_text);

        mWebview = (CustomWebview) findViewById(R.id.webview);
        mWebview.setWebViewClient(new WebViewClient());
        mWebview.getSettings().setJavaScriptEnabled(true);
        mWebview.loadUrl("http://www");

        // TODO: USE ONE AT A TIME
//        enableActivityActionmode();
//        mWebview.enableWebviewActionmodeInline(editLayout, editText);
        // this is the one we want, using TYPE_PRIMARY
        mWebview.enableWebviewActionmodeActionBar(editLayout, editText);
    }

    private void enableActivityActionmode() {
        mWebview.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                mActionMode = MainActivity.this.startActionMode(new MyActionmodeCallback(editLayout, editText));
                return false;
            }
        });
    }
}

应用/ SRC /主/ JAVA / COM / my_package / webview_edit_text / CustomWebview.java

package com.my_package.webview_edit_text;

import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ActionMode;
import android.webkit.WebView;
import android.widget.EditText;
import android.widget.LinearLayout;

import static android.view.ActionMode.TYPE_PRIMARY;

public class CustomWebview extends WebView {
    private static final String TAG = "CustomWebview";
    private boolean enableWebviewActionmodeInline = false;
    private boolean enableWebviewActionmodeActionbar = false;
    private LinearLayout editLayout;
    private EditText editText;

    public CustomWebview(Context context) {
        super(context);
    }

    public CustomWebview(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomWebview(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void enableWebviewActionmodeInline(LinearLayout editLayout, EditText editText) {
        this.enableWebviewActionmodeInline = true;
        this.editLayout = editLayout;
        this.editText = editText;
    }

    public void enableWebviewActionmodeActionBar(LinearLayout editLayout, EditText editText) {
        this.enableWebviewActionmodeActionbar = true;
        this.editLayout = editLayout;
        this.editText = editText;
    }

    @Override
    public ActionMode startActionMode(ActionMode.Callback callback) {
        if (enableWebviewActionmodeInline) {
            // custom actionmode enabled
            Log.i(TAG, "startActionMode() enableWebviewActionmodeInline");
            return super.startActionMode(new MyActionmodeCallback(editLayout, editText));
        }

        if (enableWebviewActionmodeActionbar) {
            // custom actionmode enabled
            Log.i(TAG, "startActionMode() enableWebviewActionmodeActionbar");
            return super.startActionModeForChild(this, new MyActionmodeCallback(editLayout, editText));
        }

        // default
        Log.i(TAG, "startActionMode() default");
        return super.startActionMode(callback);
    }

    @Override
    public ActionMode startActionMode(ActionMode.Callback callback, int type) {
        if (enableWebviewActionmodeInline) {
            // custom actionmode enabled
            Log.i(TAG, "startActionMode()_type enableWebviewActionmodeInline");
            return super.startActionMode(new MyActionmodeCallback(editLayout, editText), type);
        }

        if (enableWebviewActionmodeActionbar) {
            // custom actionmode enabled
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                Log.i(TAG, "startActionMode()_type enableWebviewActionmodeActionbar Build.VERSION_CODES.M");
                return super.startActionModeForChild(getRootView(), new MyActionmodeCallback(editLayout, editText), TYPE_PRIMARY);
//                return super.startActionModeForChild(this, new MyActionmodeCallback(editLayout, editText), TYPE_PRIMARY);
//                return super.startActionModeForChild(this, new MyActionmodeCallback(editLayout), TYPE_FLOATING);
            } else {
                Log.i(TAG, "startActionMode()_type enableWebviewActionmodeActionbar");
                return super.startActionModeForChild(this, new MyActionmodeCallback(editLayout, editText));
            }
        }

        // default
        Log.i(TAG, "startActionMode()_type default");
        return super.startActionMode(callback, type);
    }
}

应用/ SRC /主/ JAVA / COM / my_package / webview_edit_text / MyActionmodeCallback.java

package com.my_package.webview_edit_text;

import android.util.Log;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;

public class MyActionmodeCallback implements ActionMode.Callback {
    private static final String TAG = "MyActionmodeCallback";
    private LinearLayout editLayout;
    private EditText editText;

    public MyActionmodeCallback(LinearLayout editLayout, EditText editText) {
        this.editLayout = editLayout;
        this.editText = editText;
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        Log.i(TAG, "onActionItemClicked()");

        // TODO Auto-generated method stub
        switch (item.getItemId()) {
            case R.id.item_edit:
                Log.i(TAG, "onActionItemClicked() R.id.item_option1");
                editLayout.setVisibility(View.VISIBLE);
                return true;
        }
        return false;
    }

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        mode.getMenuInflater().inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        editLayout.setVisibility(View.GONE);
    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        mode.setTitle("onPrepareActionMode()");
        return false;
    }
}

应用/ SRC /主/ RES /布局/ activity_main.xml中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context="com.my_package.webview_edit_text.MainActivity">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!-- WEBVIEW -->
        <com.my_package.webview_edit_text.CustomWebview
            android:id="@+id/webview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

        <!-- EDIT TEXT LAYOUT -->
        <LinearLayout android:id="@+id/edit_layout"
                      xmlns:android="http://schemas.android.com/apk/res/android"
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:layout_gravity="bottom"
                      android:orientation="vertical"
                      android:visibility="gone">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="#2b2d2e"
                android:orientation="vertical">

                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="10dp"
                    android:text="Test button"/>

                <EditText
                    android:id="@+id/edit_text"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="#b48ade"
                    android:hint="Edit text here"
                    android:padding="10dp"/>
            </LinearLayout>
        </LinearLayout>
    </FrameLayout>
</RelativeLayout>

应用/ SRC /主/ RES /菜单/ menu.xml文件

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/item_edit"
        android:icon="@android:drawable/ic_menu_edit"
        android:title="Edit">
    </item>
</menu>

应用/ SRC /主/ AndroidManifest.xml中

<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.my_package.webview_edit_text"
          xmlns:android="http://schemas.android.com/apk/res/android">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

应用/ SRC /主/的build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
        applicationId "com.my_package.webview_edit_text"
        minSdkVersion 16
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
            exclude group: 'com.android.support', module: 'support-annotations'
        })
        compile 'com.android.support:appcompat-v7:25.3.1'
        compile 'com.android.support.constraint:constraint-layout:1.0.2'
        testCompile 'junit:junit:4.12'
    }

1 个答案:

答案 0 :(得分:0)

  • 而不是在 MainActivity 上使用 LinearLayout 来容纳编辑布局。使用对话框

  • 使用对话框保留 webview文字选择

  • 在Android 5.0和7.1.1上测试

Github链接(对话框分支) - &gt; https://github.com/fmarais/webview_edit_text/tree/dialog

将以下内容添加到 app / src / main / java / com / my_package / webview_edit_text / MainActivity.java

public void showDialog() {
        final Dialog dialog = new Dialog(this);
        dialog.setContentView(R.layout.dialog);

        // Setting dialogview
        Window window = dialog.getWindow();
        window.setGravity(Gravity.BOTTOM);

        window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
        dialog.setTitle("Edit");
        dialog.setContentView(R.layout.dialog);
        dialog.setCancelable(true);

        dialog.show();
    }
  • MainActivity.this 引用传递给 CustomWebview ,然后传递给 MyActionmodeCallback
  • MyActionmodeCallback onActionItemClicked()中显示使用
  • 的对话框

<强> MainActivity

mWebview.enableWebviewActionmodeActionBar(this, editLayout, editText);

<强> CustomWebview

@Override
    public ActionMode startActionMode(ActionMode.Callback callback) {
        if (enableWebviewActionmodeInline) {
            // custom actionmode enabled
            Log.i(TAG, "startActionMode() enableWebviewActionmodeInline");
            return super.startActionMode(new MyActionmodeCallback(mainActivity, this, editLayout, editText));
        }

        if (enableWebviewActionmodeActionbar) {
            // custom actionmode enabled
            Log.i(TAG, "startActionMode() enableWebviewActionmodeActionbar");
            return super.startActionMode(new MyActionmodeCallback(mainActivity, this, editLayout, editText));
        }

        // default
        Log.i(TAG, "startActionMode() default");
        return super.startActionMode(callback);
    }

    @Override
    public ActionMode startActionMode(ActionMode.Callback callback, int type) {
        if (enableWebviewActionmodeInline) {
            // custom actionmode enabled
            Log.i(TAG, "startActionMode()_type enableWebviewActionmodeInline");
            return super.startActionMode(new MyActionmodeCallback(mainActivity, this, editLayout, editText), type);
        }

        if (enableWebviewActionmodeActionbar) {
            // custom actionmode enabled
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                Log.i(TAG, "startActionMode()_type enableWebviewActionmodeActionbar Build.VERSION_CODES.M");
                return super.startActionMode(new MyActionmodeCallback(mainActivity, this, editLayout, editText), TYPE_PRIMARY);
            } else {
                Log.i(TAG, "startActionMode()_type enableWebviewActionmodeActionbar");
                return super.startActionMode(new MyActionmodeCallback(mainActivity, this, editLayout, editText));
            }
        }

        // default
        Log.i(TAG, "startActionMode()_type default");
        return super.startActionMode(callback, type);
    }

<强> MyActionmodeCallback

@Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        Log.i(TAG, "onActionItemClicked()");

        // TODO Auto-generated method stub
        switch (item.getItemId()) {
            case R.id.item_edit:
                Log.i(TAG, "onActionItemClicked() R.id.item_option1");
//                editLayout.setVisibility(View.VISIBLE);
                mainActivity.showDialog();
                return true;
        }
        return false;
    }