현재 이 글을 작성하는 시점에서 phonegap plugin인 childbrowser를 android에 적용시키면 작동되지 않는다.


플러그인이 이전 1.x대 버전으로 업로드 돼 있어 정상적으로 실행이 안된다.


단순히 페이지만 보여주는 것이라면 


2.3 이상부터는 InAppBrowser가 생겨서 childbrowser를 사용할 필요가 없지만


childbrowser를 통한 oauth인증을 위해서라면 아직 childbrowser가 필요하다.


ChildBrowser.java파일을 다음과 같이 수정하자


/*

 * PhoneGap is available under *either* the terms of the modified BSD license *or* the

 * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.

 *

 * Copyright (c) 2005-2011, Nitobi Software Inc.

 * Copyright (c) 2010-2011, IBM Corporation

 */

package com.phonegap.plugins.childBrowser;


import java.io.IOException;

import java.io.InputStream;


import org.apache.cordova.api.CordovaPlugin; //수정

import org.apache.cordova.api.PluginResult;

import org.apache.cordova.api.CallbackContext; //추가

import org.json.JSONArray;

import org.json.JSONException;

import org.json.JSONObject;


import android.app.Dialog;

import android.content.Context;

import android.content.DialogInterface;

import android.content.Intent;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.net.Uri;

import android.text.InputType;

import android.util.Log;

import android.util.TypedValue;

import android.view.Gravity;

import android.view.KeyEvent;

import android.view.View;

import android.view.Window;

import android.view.WindowManager;

import android.view.WindowManager.LayoutParams;

import android.view.inputmethod.EditorInfo;

import android.view.inputmethod.InputMethodManager;

import android.webkit.WebChromeClient;

import android.webkit.WebSettings;

import android.webkit.WebView;

import android.webkit.WebViewClient;

import android.widget.EditText;

import android.widget.ImageButton;

import android.widget.LinearLayout;

import android.widget.RelativeLayout;


public class ChildBrowser extends CordovaPlugin { //수정


    protected static final String LOG_TAG = "ChildBrowser";

    private static int CLOSE_EVENT = 0;

    private static int LOCATION_CHANGED_EVENT = 1;


//    private String browserCallbackId = null; //삭제

    private CallbackContext context; //추가


    private Dialog dialog;

    private WebView webview;

    private EditText edittext;

    private boolean showLocationBar = true;


    /**

     * Executes the request and returns PluginResult.

     *

     * @param action        The action to execute.

     * @param args          JSONArry of arguments for the plugin.

     * @param callbackId    The callback id used when calling back into JavaScript.

     * @return              A PluginResult object with a status and message.

     */

//    public PluginResult execute(String action, JSONArray args, String callbackId) { //삭제

    @Override

    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException{  //추가

        PluginResult.Status status = PluginResult.Status.OK;

        this.context=callbackContext;//추가

        String result = "";


        try {

            if (action.equals("showWebPage")) {

//                this.browserCallbackId = callbackId;  //삭제


                // If the ChildBrowser is already open then throw an error

                if (dialog != null && dialog.isShowing()) {

//                    return new PluginResult(PluginResult.Status.ERROR, "ChildBrowser is already open");  //삭제

                this.context.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, "ChlildBrowser is already open"));  //추가

                return true; //추가

                }


                result = this.showWebPage(args.getString(0), args.optJSONObject(1));


                if (result.length() > 0) {

                    status = PluginResult.Status.ERROR;

//                    return new PluginResult(status, result); //삭제

                    this.context.sendPluginResult(new PluginResult(status, result));  //추가

                } else {

                    PluginResult pluginResult = new PluginResult(status, result);

                    pluginResult.setKeepCallback(true);

//                    return pluginResult;  //삭제

                    this.context.sendPluginResult(pluginResult);  //추가

                    return true;  //추가

                }

            }

            else if (action.equals("close")) {

                closeDialog();


                JSONObject obj = new JSONObject();

                obj.put("type", CLOSE_EVENT);


                PluginResult pluginResult = new PluginResult(status, obj);

                pluginResult.setKeepCallback(false);

//                return pluginResult;  //삭제

                this.context.sendPluginResult(pluginResult);  //추가

                return true;  //추가

            }

            else if (action.equals("openExternal")) {

                result = this.openExternal(args.getString(0), args.optBoolean(1));

                if (result.length() > 0) {

                    status = PluginResult.Status.ERROR;

                }

            }

            else {

                status = PluginResult.Status.INVALID_ACTION;

            }

//            return new PluginResult(status, result);  //삭제

            this.context.sendPluginResult(new PluginResult(status, result));  //추가

            return true;  //추가

        } catch (JSONException e) {

//            return new PluginResult(PluginResult.Status.JSON_EXCEPTION);  //삭제

        this.context.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));  //추가

        return true;  //추가

        }

    }


    /**

     * Display a new browser with the specified URL.

     *

     * @param url           The url to load.

     * @param usePhoneGap   Load url in PhoneGap webview

     * @return              "" if ok, or error message.

     */

    public String openExternal(String url, boolean usePhoneGap) {

        try {

            Intent intent = null;

            if (usePhoneGap) {

                intent = new Intent().setClass(this.cordova.getActivity(), org.apache.cordova.DroidGap.class);

                intent.setData(Uri.parse(url)); // This line will be removed in future.

                intent.putExtra("url", url);


                // Timeout parameter: 60 sec max - May be less if http device timeout is less.

                intent.putExtra("loadUrlTimeoutValue", 60000);


                // These parameters can be configured if you want to show the loading dialog

                intent.putExtra("loadingDialog", "Wait,Loading web page...");   // show loading dialog

                intent.putExtra("hideLoadingDialogOnPageLoad", true);           // hide it once page has completely loaded

            }

            else {

                intent = new Intent(Intent.ACTION_VIEW);

                intent.setData(Uri.parse(url));

            }

            this.cordova.getActivity().startActivity(intent);

            return "";

        } catch (android.content.ActivityNotFoundException e) {

            Log.d(LOG_TAG, "ChildBrowser: Error loading url "+url+":"+ e.toString());

            return e.toString();

        }

    }


    /**

     * Closes the dialog

     */

    private void closeDialog() {

        if (dialog != null) {

            dialog.dismiss();

        }

    }


    /**

     * Checks to see if it is possible to go back one page in history, then does so.

     */

    private void goBack() {

        if (this.webview.canGoBack()) {

            this.webview.goBack();

        }

    }


    /**

     * Checks to see if it is possible to go forward one page in history, then does so.

     */

    private void goForward() {

        if (this.webview.canGoForward()) {

            this.webview.goForward();

        }

    }


    /**

     * Navigate to the new page

     *

     * @param url to load

     */

    private void navigate(String url) {

        InputMethodManager imm = (InputMethodManager)this.cordova.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);

        imm.hideSoftInputFromWindow(edittext.getWindowToken(), 0);


        if (!url.startsWith("http") && !url.startsWith("file:")) {

            this.webview.loadUrl("http://" + url);

        } else {

            this.webview.loadUrl(url);

        }

        this.webview.requestFocus();

    }



    /**

     * Should we show the location bar?

     *

     * @return boolean

     */

    private boolean getShowLocationBar() {

        return this.showLocationBar;

    }


    /**

     * Display a new browser with the specified URL.

     *

     * @param url           The url to load.

     * @param jsonObject

     */

    public String showWebPage(final String url, JSONObject options) {

        // Determine if we should hide the location bar.

        if (options != null) {

            showLocationBar = options.optBoolean("showLocationBar", true);

        }


        // Create dialog in new thread

        Runnable runnable = new Runnable() {

            /**

             * Convert our DIP units to Pixels

             *

             * @return int

             */

            private int dpToPixels(int dipValue) {

                int value = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP,

                                                            (float) dipValue,

                                                            cordova.getActivity().getResources().getDisplayMetrics()

                );


                return value;

            }


            public void run() {

                // Let's create the main dialog

                dialog = new Dialog(cordova.getActivity(), android.R.style.Theme_NoTitleBar);

                dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog;

                dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);

                dialog.setCancelable(true);

                dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {

                        public void onDismiss(DialogInterface dialog) {

                            try {

                                JSONObject obj = new JSONObject();

                                obj.put("type", CLOSE_EVENT);


                                sendUpdate(obj, false);

                            } catch (JSONException e) {

                                Log.d(LOG_TAG, "Should never happen");

                            }

                        }

                });


                // Main container layout

                LinearLayout main = new LinearLayout(cordova.getActivity());

                main.setOrientation(LinearLayout.VERTICAL);


                // Toolbar layout

                RelativeLayout toolbar = new RelativeLayout(cordova.getActivity());

                toolbar.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, this.dpToPixels(44)));

                toolbar.setPadding(this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2));

                toolbar.setHorizontalGravity(Gravity.LEFT);

                toolbar.setVerticalGravity(Gravity.TOP);


                // Action Button Container layout

                RelativeLayout actionButtonContainer = new RelativeLayout(cordova.getActivity());

                actionButtonContainer.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

                actionButtonContainer.setHorizontalGravity(Gravity.LEFT);

                actionButtonContainer.setVerticalGravity(Gravity.CENTER_VERTICAL);

                actionButtonContainer.setId(1);


                // Back button

                ImageButton back = new ImageButton(cordova.getActivity());

                RelativeLayout.LayoutParams backLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);

                backLayoutParams.addRule(RelativeLayout.ALIGN_LEFT);

                back.setLayoutParams(backLayoutParams);

                back.setContentDescription("Back Button");

                back.setId(2);

                try {

                    back.setImageBitmap(loadDrawable("www/childbrowser/icon_arrow_left.png"));

                } catch (IOException e) {

                    Log.e(LOG_TAG, e.getMessage(), e);

                }

                back.setOnClickListener(new View.OnClickListener() {

                    public void onClick(View v) {

                        goBack();

                    }

                });


                // Forward button

                ImageButton forward = new ImageButton(cordova.getActivity());

                RelativeLayout.LayoutParams forwardLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);

                forwardLayoutParams.addRule(RelativeLayout.RIGHT_OF, 2);

                forward.setLayoutParams(forwardLayoutParams);

                forward.setContentDescription("Forward Button");

                forward.setId(3);

                try {

                    forward.setImageBitmap(loadDrawable("www/childbrowser/icon_arrow_right.png"));

                } catch (IOException e) {

                    Log.e(LOG_TAG, e.getMessage(), e);

                }

                forward.setOnClickListener(new View.OnClickListener() {

                    public void onClick(View v) {

                        goForward();

                    }

                });


                // Edit Text Box

                edittext = new EditText(cordova.getActivity());

                RelativeLayout.LayoutParams textLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);

                textLayoutParams.addRule(RelativeLayout.RIGHT_OF, 1);

                textLayoutParams.addRule(RelativeLayout.LEFT_OF, 5);

                edittext.setLayoutParams(textLayoutParams);

                edittext.setId(4);

                edittext.setSingleLine(true);

                edittext.setText(url);

                edittext.setInputType(InputType.TYPE_TEXT_VARIATION_URI);

                edittext.setImeOptions(EditorInfo.IME_ACTION_GO);

                edittext.setInputType(InputType.TYPE_NULL); // Will not except input... Makes the text NON-EDITABLE

                edittext.setOnKeyListener(new View.OnKeyListener() {

                    public boolean onKey(View v, int keyCode, KeyEvent event) {

                        // If the event is a key-down event on the "enter" button

                        if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {

                          navigate(edittext.getText().toString());

                          return true;

                        }

                        return false;

                    }

                });


                // Close button

                ImageButton close = new ImageButton(cordova.getActivity());

                RelativeLayout.LayoutParams closeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);

                closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);

                close.setLayoutParams(closeLayoutParams);

                forward.setContentDescription("Close Button");

                close.setId(5);

                try {

                    close.setImageBitmap(loadDrawable("www/childbrowser/icon_close.png"));

                } catch (IOException e) {

                    Log.e(LOG_TAG, e.getMessage(), e);

                }

                close.setOnClickListener(new View.OnClickListener() {

                    public void onClick(View v) {

                        closeDialog();

                    }

                });


                // WebView

                webview = new WebView(cordova.getActivity());

                webview.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));

                webview.setWebChromeClient(new WebChromeClient());

                WebViewClient client = new ChildBrowserClient(edittext);

                webview.setWebViewClient(client);

                WebSettings settings = webview.getSettings();

                settings.setJavaScriptEnabled(true);

                settings.setJavaScriptCanOpenWindowsAutomatically(true);

                settings.setBuiltInZoomControls(true);

                settings.setPluginsEnabled(true);

                settings.setDomStorageEnabled(true);

                webview.loadUrl(url);

                webview.setId(6);

                webview.getSettings().setLoadWithOverviewMode(true);

                webview.getSettings().setUseWideViewPort(true);

                webview.requestFocus();

                webview.requestFocusFromTouch();


                // Add the back and forward buttons to our action button container layout

                actionButtonContainer.addView(back);

                actionButtonContainer.addView(forward);


                // Add the views to our toolbar

                toolbar.addView(actionButtonContainer);

                toolbar.addView(edittext);

                toolbar.addView(close);


                // Don't add the toolbar if its been disabled

                if (getShowLocationBar()) {

                    // Add our toolbar to our main view/layout

                    main.addView(toolbar);

                }


                // Add our webview to our main view/layout

                main.addView(webview);


                WindowManager.LayoutParams lp = new WindowManager.LayoutParams();

                lp.copyFrom(dialog.getWindow().getAttributes());

                lp.width = WindowManager.LayoutParams.FILL_PARENT;

                lp.height = WindowManager.LayoutParams.FILL_PARENT;


                dialog.setContentView(main);

                dialog.show();

                dialog.getWindow().setAttributes(lp);

            }


          private Bitmap loadDrawable(String filename) throws java.io.IOException {

              InputStream input = cordova.getActivity().getAssets().open(filename);

              return BitmapFactory.decodeStream(input);

          }

        };

        this.cordova.getActivity().runOnUiThread(runnable);

        return "";

    }


    /**

     * Create a new plugin result and send it back to JavaScript

     *

     * @param obj a JSONObject contain event payload information

     */

    private void sendUpdate(JSONObject obj, boolean keepCallback) {

//        if (this.browserCallbackId != null) {  //삭제

    if(this.context!=null){  //추가

            PluginResult result = new PluginResult(PluginResult.Status.OK, obj);

            result.setKeepCallback(keepCallback);

//            this.success(result, this.browserCallbackId);  //삭제

            this.context.sendPluginResult(result);  //추가

        }

    }


    /**

     * The webview client receives notifications about appView

     */

    public class ChildBrowserClient extends WebViewClient {

        EditText edittext;


        /**

         * Constructor.

         *

         * @param mContext

         * @param edittext

         */

        public ChildBrowserClient(EditText mEditText) {

            this.edittext = mEditText;

        }


        /**

         * Notify the host application that a page has started loading.

         *

         * @param view          The webview initiating the callback.

         * @param url           The url of the page.

         */

        @Override

        public void onPageStarted(WebView view, String url,  Bitmap favicon) {

            super.onPageStarted(view, url, favicon);

            String newloc;

            if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:")) {

                newloc = url;

            } else {

                newloc = "http://" + url;

            }


            if (!newloc.equals(edittext.getText().toString())) {

                edittext.setText(newloc);

            }


            try {

                JSONObject obj = new JSONObject();

                obj.put("type", LOCATION_CHANGED_EVENT);

                obj.put("location", url);


                sendUpdate(obj, true);

            } catch (JSONException e) {

                Log.d("ChildBrowser", "This should never happen");

            }

        }

    }

}




android localnotification을 사용하면


알람 후 알림창에 알림을 선택하면 앱이 실행되지 않는다.


알림창의 알림을 선택하면 앱이 실행하게 하려면


플러그인 파일중


AlarmReceiver.java 파일을 수정해야 한다.


파일을 열고


final PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(), 0);  -->이부분을


final PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(context, 프로젝트이름.class), 0);


다음과 같이 고치면 된다.

http://docs.phonegap.com/en/2.7.0/cordova_inappbrowser_inappbrowser.md.html#InAppBrowser

위 주소로 가면 모든 내용을 확인할 수 있다.


cordova 2.3 이상부터 플러그인인 childbrowser를 쓸 필요가 없어졌다.


phonegap에서 childbrowser를 InAppBrowser라는 이름으로 지원해 준다.


사용방법은 다음과 같다.


안드로이드는


app->res->xml->config.xml 에 다음과 같이 추가한다.


<plugin name="InAppBrowser" value="org.apache.cordova.InAppBrowser" />


ios는


config.xml에 다음과 같이 추가한다.


<plugin name="InAppBrowser" value="CDVInAppBrowser" />

그리고 javascript상에 다음과 같이 입력하면

window.open('http://apache.org', '_blank', 'location=yes');


InAppBrowser가 실행된다.

line chart의 최근 데이터는 그래프의 끝에 위치하게 되서 점도 반절정도 잘리고 선택하기도 좀 불편할때가 있다.



이 chart의 마지막 점을 한칸 앞으로 당기는 방법은 마지막 데이터에 'nan'(Not A Number)값을 넣어주면 된다.


정리하면 데이터 저장후 마지막 데이터에 nan값을 추가로 넣어주고 다시 데이터가 삽일될때 마지막 데이터에 정보를 저장 후


다시 nan값을 마지막에 추가로 넣어준다.


마지막이 빈공간으로 표현되 한칸 앞으로 당겨진 효과가 나타나난다.



로컬스토리지에 저장된 데이터를 보면 다음과 같다.




http://www.sencha.com/products/touch/download/ 로 이동해 센차 gpl버전을 다운받습니다.




그리고 http://www.sencha.com/products/sencha-cmd/download 들어가 cmd를 다운받습니다.



cmd를 설치해야 mvc형식으로 프로젝트를 생성하고 빌드를 할 수 있습니다.


다운을 받아 압축을 풀고 설치를 합니다.


설치가 완료되면 터미널 창으로 띄운후 다음과 같이 입력해 sencha touch프로젝트를 생성합니다.


sencha -sdk <다운받은 sencha gpl폴더경로> generate app <프로젝트 이름> <프로젝트가 생성될 경로>



다음과 같이 프로젝트가 생성됩니다.


sencha touch를 사용하다보면 네이티브 기능을 활용할때가 있다습니다.


센차터치에서도 네이티브 기능을 사용할 수 있지만 기능도 적고 phonegap은 수많은 플러그인이 있기 때문에 많은 기능을 쉽게


활용할 수 있습니다.


그리고 직접 네이티브 기능을 쓰는 플러그인도 만들 수 있습니다.


다음에는 직접 phonegap 플러그인 만드는 방법을 포스팅하겠습니다.


이 phonegap과 sencha touch를 연동하는 방법을 잘 모르시는분이 많아서 설명해 보겠습니다.


일단 폴더를 하나 만든후 폴더안에 2개의 폴더를 만듭니다.



저는 SenchaTouch라는 폴더를 만든 후 phonegap 폴더와 sencha폴더를 만들었습니다.


phonegap폴더에는 phonegap프로젝트를 생성할 것이고 sencha 폴더에는 sencha touch프로젝트를 생성할 것입니다.


같이 관리하기 쉽게 하기 위해서 한폴더 안에 생성했습니다.


우선 phonegap프로젝트먼저 생성해 보겠습니다.


http://phonegap.com/ 사이트로 가서 phonegap을 다운받습니다.





다운을 받은 후 압축을 풀고 


아래 그림과 같은 경로로 들어가보면 bin폴더가 있습니다.





이제 터미널창으로 이용해서 프로젝트를 생성해 보겠습니다.


터미널을 띄우고 위의 bin경로로 이동합니다.


쉽게 이동하는 방법은 cd를 입력후 bin폴더를 터미널창에 끌어다 놓거나




bin 폴더를 바로 터미널 실행아이콘으로 끌어다 놓는 방법이 있습니다.



이렇게 이동후 프로젝트를 생성하는 방법은 다음과 같이 입력합니다.


./create <프로젝트가 생성될 폴더> <페키지 이름> <프로젝트 이름>



다음과 같이 ios phonegap 프로젝트가 생성됩니다.



이제 phonegap의 www폴더안에 있는 cordova파일을 sencha 폴더로 이동하고 기존의 www폴더는 삭제합니다.






이제 sencha 프로젝트를 생성해 연동시켜보도록 하겠습니다.


http://www.sencha.com/products/touch/download/ 로 이동해 센차 gpl버전을 다운받습니다.




그리고 http://www.sencha.com/products/sencha-cmd/download 들어가 cmd를 다운받습니다.



cmd를 설치해야 mvc형식으로 프로젝트를 생성하고 빌드를 할 수 있습니다.


다운을 받아 압축을 풀고 설치를 합니다.


설치가 완료되면 터미널 창으로 띄운후 다음과 같이 입력해 sencha touch프로젝트를 생성합니다.


sencha -sdk <다운받은 sencha gpl폴더경로> generate app <프로젝트 이름> <프로젝트가 생성될 경로>



다음과 같이 프로젝트가 생성됩니다.



이제 생성된 파일중 app.json파일을 수정해야 합니다.


app.json파일을 열어 이전에 phonagap폴더에서 가져온 cordova.js파일을 추가해줍니다.




이제 마지막으로 phonegap 폴더안에 www폴더를 생성해야 합니다.


터미널 창에서 다음과 같이 입력합니다.


ln -s <sencha 프로젝트 경로> <phonagap 프로젝트 경로 /www>


다시 말하면 ln -s를 입력 후 처음에 한폴더에 생성한 두개의 프로젝트중 sencha 프로젝트를 터미널창에 끌어다놓고 다음으로 


phonegap프로젝트를 끌어다 놓은후 뒤에 /www를 붙어주고 입력합니다.



이렇게 입력하면 phonagap폴더안에 www폴더가 생성되고 이 폴더안에 sencha폴더 내용이 들어있습니다.





이제 xcode를 열고 실행해 보면




다음과 같이 잘 연동되는걸 확인할 수 있습니다.




안드로이드도 같은 방식으로 하면됩니다.


다운받은 phonegap폴더 lib->android->bin 폴더를 가지고 아이폰과 같은 방식으로 프로젝트를 생성후


./create <프로젝트가 생성될 폴더> <페키지 이름> <프로젝트 이름>


assets 폴더안에 www폴더를 생성하면 됩니다.


ln -s <sencha 프로젝트 경로> <phonagap 프로젝트 경로 /www>

sencha touch 에서 300개 이상의 icon을 제공한다.


하지만 기본적으로 쓸 수 있는건 20여개 정도다 이 300여개 icon 사용법을 알아보자


생성한 프로젝트 폴더안이나 다운받은 센차폴더안에 touch-> resources-> themes-> images-> default-> pictos 폴더안을 보면


수많은 icon이미지들이 있다.




이 아이콘을 센차에서 사용하는 방법을 살펴보자


우선 사용할 아이콘을 고른후 


resources-> sass-> 사용자 scss파일(프로젝트 생성시 app.scss이 적용된다)에 쓰고 싶은 아이콘을 추가한다.




이 scss파일을 컴파일 해야 이 아이콘 이미지들을 사용할 수 있다.


컴파일을 하면 이 scss파일을 참조해 css파일을 생성합니다. 


우리는 이 생성된 css 파일을 사용하게 되는 것입니다.


터미널 창에서 sass폴더로 경로를 이동합니다.


이동방법을 모르면 cd를 입력후 해당 폴더를 터미널 창에 끌어다 놓습니다.




그리고 compass compile <scss파일이름>을 입력해 컴파일 합니다.



컴파일이 끝나면 이미지를 사용할 수 있습니다.


사용은 iconCls에 추가한 이미지 이름을 그대로 사용하면 됩니다.





다음과 같이 추가된 icon 이미지가 나타납니다.




sencha touch 로 달력 구현은 이 플러그인이면 되겠네요


월간, 주간, 일간 까지 구현돼 있고 이벤트 추가시 달력에 표시까지 됩니다.


Download : https://github.com/SwarmOnline/Ext.ux.TouchCalendar


Documentation : http://www.swarmonline.com/Ext.ux.TouchCalendar/docs/ 




분명 store도 잘 지정해 주고 틀린곳이 없다고 생각하고 몇번이나 다시 봐도 이상이 없었다.


문제는 layout을 지정해 주지 않은것


layout을 fit으로 지정해 주니 리스트가 잘 나타났다.




작업을 하다보면 label의 width값이 글자보다 작아 글씨가 잘리는 경우가 발생한다.


이럴때 width값을 조정하려면 


laebelWidth로 설정해주면된다.





+ Recent posts