Search code examples
javaandroidxmlcordovacordova-plugins

Cordova Custom Android Layout Plugin


I am developing an android cordova custom layout plugin. When user click on a button, application will call the android plugin and display custom layout. User can move the object in the custom layout of android cordova plugin. However, I have problem with my plugin when I call my xml file in my java code. The following is my code.

src/android/CustomLayout.java

public class CustomLayout extends CordovaPlugin {
    private static final String LOG_TAG = "CustomNotification";
    public CallbackContext callbackContext;
    Context context;
    Resources resources;
    String packageName;

    public CustomLayout(){

    }

    @Override
    public boolean execute(String action, String rawArgs, CallbackContext callbackContext) throws JSONException {
        this.callbackContext = callbackContext;

        context = cordova.getActivity().getApplicationContext();
        resources = context.getResources();
        packageName = context.getPackageName();

        if (action.equals("layout")) {
            customLayout();
            return true;
        }
        return false;
    }

    private void customLayout() {
        Log.e(TAG, "show");
        cordova.getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                cordova.getActivity().setContentView(resources.getIdentifier("custom_layout", "layout", packageName));
                ImageView motion = (ImageView) cordova.getActivity().findViewById(resources.getIdentifier("tvDragMe","id",packageName));
                motion.setOnTouchListener(new MyTouchListener());
            }
        });
    }
}

class MyTouchListener implements View.OnTouchListener {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            ClipData data = ClipData.newPlainText("", "");
            View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
            view.startDrag(data, shadowBuilder, view, 0);
            view.setVisibility(View.INVISIBLE);
            return true;
        } else {
            return false;
        }
    }
}

www/customlayout.js

var exec = require('cordova/exec');
var platform = require('cordova/platform');

module.exports = {

    alert: function(completeCallback) {

        exec(completeCallback, null, "CustomLayout", "layout", []);
    }
};

res/layout/custom_layout.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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin">


    <ImageView
        android:id="@+id/tvDragMe"
        android:src="@drawable/smiles"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@android:color/holo_blue_light"
        android:padding="10dp"
        android:textColor="#ffffff"
        android:layout_marginTop="35dp"
        android:text="Drag Me" />
</RelativeLayout>

XML file

<?xml version="1.0" encoding="UTF-8"?>

<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
           id="cordova-plugin-custom_layout" version="1.0.0">

    <name>Custom Layout</name>
    <description>Cordova Custom Layout Plugin</description>
    <keywords>cordova,layout</keywords>

    <js-module src="www/customlayout.js" name="customlayout">
        <merges target="customlayout" />
    </js-module>

    <platform name="android">
        <config-file target="res/xml/config.xml" parent="/*">
            <feature name="CustomLayout">
                <param name="android-package" value="org.apache.cordova.dialogs.CustomLayout"/>
            </feature>
        </config-file>

        <source-file src="res/layout/custom_layout.xml" target-dir="res/layout/custom_layout.xml" />
    </platform>
</plugin>

Solution

  • The following is the source code my question because I don't set view and setViewByID in my Java file. The following source code is the answer.

    src/android/CustomLayout.java public class CustomLayout extends CordovaPlugin {

    private static final String LOG_TAG = "CustomLayout";
    
    
    public CustomLayout() {
    }
    
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
    
        if (action.equals("alert")) {
            this.alert();
            return true;
        }
        return false;
    }
    
    public synchronized void alert() {
        final CordovaInterface cordova = this.cordova;
    
        Runnable runnable = new Runnable() {
            public void run() {
                AlertDialog.Builder dlg = new AlertDialog.Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
                Application app = cordova.getActivity().getApplication();
                String package_name = app.getPackageName();
                Resources resources = app.getResources();
    
                int layout = resources.getIdentifier("customlayout", "layout", package_name);
                int image = resources.getIdentifier("tvDragMe", "id", package_name);
    
                LayoutInflater inflater =  cordova.getActivity().getLayoutInflater();
                View customview = inflater.inflate(layout, null);
                dlg.setView(customview);
                ImageView motion = (ImageView) customview.findViewById(image);
                motion.setOnTouchListener(new MyTouchListener());
                dlg.create();
                dlg.show();
            };
        };
        this.cordova.getActivity().runOnUiThread(runnable);
    }
    
    private class MyTouchListener implements View.OnTouchListener {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                ClipData data = ClipData.newPlainText("", "");
                View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
                view.startDrag(data, shadowBuilder, view, 0);
                view.setVisibility(View.INVISIBLE);
                return true;
            } else {
                return false;
            }
        }
    }
    

    XML file

    <name>Layout</name>
    <description>Cordova Custom Dialog Layout Plugin</description>
    <keywords>cordova,layout</keywords>
    
    <js-module src="www/customlayout.js" name="customlayout">
        <merges target="customlayout" />
    </js-module>
    
    <!-- android -->
    <platform name="android">
        <config-file target="res/xml/config.xml" parent="/*">
            <feature name="CustomLayout">
                <param name="android-package" value="org.apache.cordova.dialogs.CustomLayout"/>
            </feature>
        </config-file>
    
        <source-file src="src/android/CustomLayout.java" target-dir="src/org/apache/cordova/dialogs" />
        <source-file src="src/android/res/drawable/smiles.jpg" target-dir="res/drawable" />
        <source-file src="src/android/res/layout/customlayout.xml" target-dir="res/layout" />
    </platform>