diff --git a/.gitignore b/.gitignore index afbdab3..53fcaff 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,49 @@ -.gradle -/local.properties -/.idea/workspace.xml -/.idea/libraries -.DS_Store -/build +### Android template +# Built application files +*.apk +*.ap_ + +# Files for the Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ + +# Gradle files +.gradle/ +build/ +/*/build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + + +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion + +*.iml + +## Directory-based project format: +.idea/ + +## File-based project format: +*.ipr +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + + + diff --git a/.idea/misc.xml b/.idea/misc.xml index e3c7a0a..17b28fe 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,8 +1,5 @@ - - - @@ -40,98 +37,9 @@ - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - localhost - 5050 - - diff --git a/QCircle-Design-Template.iml b/QCircle-Design-Template.iml index 2a02201..0bb6048 100644 --- a/QCircle-Design-Template.iml +++ b/QCircle-Design-Template.iml @@ -1,5 +1,5 @@ - + @@ -7,9 +7,7 @@ - - - + diff --git a/README.md b/README.md index dc1c29a..667d143 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ how to utilize the LG QCircle design template that is irrelevant with developing The QCircle-Design-Template Library is pushed to Maven Central, so you just need to add the following dependency to your `build.gradle`. ```groovy -compile 'com.lge.developer:qcircle-design-template:1.0.0' +compile 'com.lge.developer:qcircle-design-template:2.0.0' ``` # Directories diff --git a/Sample_BeanbirdInCircle/Sample_BeanbirdInCircle.iml b/Sample_BeanbirdInCircle/Sample_BeanbirdInCircle.iml index 698b1c0..01c5cb4 100644 --- a/Sample_BeanbirdInCircle/Sample_BeanbirdInCircle.iml +++ b/Sample_BeanbirdInCircle/Sample_BeanbirdInCircle.iml @@ -1,5 +1,5 @@ - + @@ -9,6 +9,7 @@ + @@ -79,7 +81,6 @@ - diff --git a/Sample_SimpleCircle/Sample_SimpleCircle.iml b/Sample_SimpleCircle/Sample_SimpleCircle.iml index f016b01..5c3861a 100644 --- a/Sample_SimpleCircle/Sample_SimpleCircle.iml +++ b/Sample_SimpleCircle/Sample_SimpleCircle.iml @@ -1,5 +1,5 @@ - + @@ -9,6 +9,7 @@ + @@ -79,7 +81,6 @@ - diff --git a/designTemplate/designTemplate.iml b/designTemplate/designTemplate.iml index f7008e6..e4dedb4 100644 --- a/designTemplate/designTemplate.iml +++ b/designTemplate/designTemplate.iml @@ -1,5 +1,5 @@ - + @@ -9,6 +9,7 @@ + diff --git a/designTemplate/src/main/java/com/lge/qcircle/template/QCircleBackButton.java b/designTemplate/src/main/java/com/lge/qcircle/template/QCircleBackButton.java index 338d425..d1c1ea0 100644 --- a/designTemplate/src/main/java/com/lge/qcircle/template/QCircleBackButton.java +++ b/designTemplate/src/main/java/com/lge/qcircle/template/QCircleBackButton.java @@ -1,16 +1,13 @@ package com.lge.qcircle.template; import android.app.Activity; -import android.content.ContentResolver; import android.content.Context; import android.graphics.Color; -import android.provider.Settings; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.widget.ImageView; -import android.widget.ImageView.ScaleType; import android.widget.RelativeLayout; import com.lge.qcircle.utils.QCircleFeature; @@ -20,46 +17,95 @@ * * @author jeongeun.jeon */ -public final class QCircleBackButton extends QCircleTemplateElement{ +public final class QCircleBackButton extends QCircleTemplateElement { - private final String TAG = "QCircleBackButton"; + private final String TAG = "QCircleBackButton"; private OnClickListener mListener; private ImageView mBtnContent = null; - private int mButtonHeight = 0; + private int mButtonHeight = 0; private boolean isDark = false; + private static float PADDING_RATIO = 0.35f; + //sujin.cho + private final float fixedButtonRatio = 0.23f; + private RelativeLayout.LayoutParams mParams = null; + // layout values + private static int mFullSize = 0; // circle diameter - private static float PADDING_RATIO = 0.35f; - //sujin.cho - private final float fixedButtonRatio = 0.23f; - private RelativeLayout.LayoutParams mParams = null; + /** + * creates a back button. + * + * @param context {@code Activity} which has a circle view.
+ * If it is null, you might get errors when you use method of this class. + */ + public QCircleBackButton(Context context) { + mContext = context; + mFullSize = QCircleFeature.getTemplateDiameter(context); + mButtonHeight = (int) (fixedButtonRatio * mFullSize); + if (!setButton()) + Log.d(TAG, "Cannot create a button. Context is null."); + } - // layout values - private static int mFullSize = 0; // circle diameter + /** + * creates a back button. + * + * @param context {@code Activity} which has a circle view.
+ * @param listener Listener on click + * If it is null, you might get errors when you use method of this class. + */ + public QCircleBackButton(Context context, OnClickListener listener) { + this(context); + mListener = listener; + } + /** + * creates a back button. + * + * @param context {@code Activity} which has a circle view.
+ * @param theme Theme for button + * @param isTransparent is the button transparent + *

+ * If it is null, you might get errors when you use method of this class. + */ + public QCircleBackButton(Context context, ButtonTheme theme, boolean isTransparent, OnClickListener listener) { + this(context, theme, isTransparent); + mListener = listener; + } - /** - * creates a back button. - * - * @param context {@code Activity} which has a circle view.
- * If it is null, you might get errors when you use method of this class. - */ - public QCircleBackButton(Context context) { - mContext = context; - getTemplateDiameter(context); - mButtonHeight = (int)(fixedButtonRatio * mFullSize); - if (!setButton()) - Log.d(TAG, "Cannot create a button. Context is null."); - } + /** + * creates a back button. + * + * @param context {@code Activity} which has a circle view.
+ * @param theme Theme for button + * @param isTransparent is the button transparent + *

+ * If it is null, you might get errors when you use method of this class. + */ + public QCircleBackButton(Context context, ButtonTheme theme, boolean isTransparent) { + this(context, theme); + if (isTransparent) setBackgroundTransparent(); + } + /** + * creates a back button. + * + * @param context {@code Activity} which has a circle view.
+ * @param theme Theme for button + *

+ * If it is null, you might get errors when you use method of this class. + */ + public QCircleBackButton(Context context, ButtonTheme theme) { + this(context); + setTheme(theme); + } /** * creates a back button. * * @param context {@code Activity} which has a circle view.
* If it is null, you might get errors when you use method of this class. */ - /* + /* public QCircleBackButton(Context context, float heightRatio) { mContext = context; @@ -74,8 +120,8 @@ public QCircleBackButton(Context context, float heightRatio) { /** * creates a back button. * - * @param context {@code Activity} which has a circle view.
- * If it is null, you might get errors when you use method of this class. + * @param context {@code Activity} which has a circle view.
+ * If it is null, you might get errors when you use method of this class. * @param listener Listener on click */ public QCircleBackButton(Context context, int height, OnClickListener listener) { @@ -96,10 +142,10 @@ private boolean setButton() { boolean result = false; if (mContext != null) { mBtnContent = new ImageView(mContext); - mBtnContent.setPadding(0,(int)(mButtonHeight*PADDING_RATIO), 0, (int)(mButtonHeight*PADDING_RATIO)); + mBtnContent.setPadding(0, (int) (mButtonHeight * PADDING_RATIO), 0, (int) (mButtonHeight * PADDING_RATIO)); // set attributes mBtnContent.setId(R.id.backButton); - initTheme(); + initTheme(); mBtnContent.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { @@ -118,47 +164,46 @@ public void onClick(View v) { return result; } - /** - * sets theme of the back button. - * @author Yoav Sternberg - */ + /** + * sets theme of the back button. + * + * @author Yoav Sternberg + */ private void initTheme() { mBtnContent.setImageResource(isDark ? R.drawable.backover_dark : R.drawable.backover); mBtnContent.setBackgroundResource(isDark ? R.drawable.back_button_background_dark : R.drawable.back_button_background); } - /** - * Uses dark theme for the back button.

- * - * @param isDark flag which indicates whether dark theme is used or not. - * @author Yoav Sternberg - * @deprecated - */ + /** + * Uses dark theme for the back button.

+ * + * @param isDark flag which indicates whether dark theme is used or not. + * @author Yoav Sternberg + * @deprecated + */ public void isDark(boolean isDark) { this.isDark = isDark; - initTheme(); - } - - /** - * Sets a theme for the back button. This provides three types of themes. - * - * @param type - */ - public void setTheme(ButtonTheme type) - { - if(mBtnContent != null) { - if (type == ButtonTheme.DARK) { - mBtnContent.setImageResource(R.drawable.backover_dark); - mBtnContent.setBackgroundResource(R.drawable.back_button_background_dark); - } else if (type == ButtonTheme.LIGHT) { - mBtnContent.setImageResource(R.drawable.backover); - mBtnContent.setBackgroundResource(R.drawable.back_button_background); - } else if (type == ButtonTheme.TRANSPARENT) { - mBtnContent.setBackgroundColor(Color.TRANSPARENT); - } - } - } + initTheme(); + } + /** + * Sets a theme for the back button. This provides three types of themes. + * + * @param type + */ + public void setTheme(ButtonTheme type) { + if (mBtnContent != null) { + if (type == ButtonTheme.DARK) { + mBtnContent.setImageResource(R.drawable.backover_dark); + mBtnContent.setBackgroundResource(R.drawable.back_button_background_dark); + } else if (type == ButtonTheme.LIGHT) { + mBtnContent.setImageResource(R.drawable.backover); + mBtnContent.setBackgroundResource(R.drawable.back_button_background); + } else if (type == ButtonTheme.TRANSPARENT) { + mBtnContent.setBackgroundColor(Color.TRANSPARENT); + } + } + } /** * Gets the view of the button. @@ -186,60 +231,35 @@ public void setBackgroundTransparent() { mBtnContent.setBackgroundResource(R.drawable.back_button_background_semi_transparent); } - /** - * Adds this to the template. - * @param parent - * @author sujin.cho - */ - @Override - protected void addTo(RelativeLayout parent, RelativeLayout content) { - if ((mBtnContent != null) && (parent != null)) { - setLayoutParams(); - parent.addView(mBtnContent); - adjustLayout(content); - } - } - - private void adjustLayout(RelativeLayout content) - { - RelativeLayout.LayoutParams contentParams = (RelativeLayout.LayoutParams) content.getLayoutParams(); - contentParams.addRule(RelativeLayout.ABOVE, mBtnContent.getId()); - content.setLayoutParams(contentParams); - } - - /** - * sets layout parameters of the back button. - * - */ - private void setLayoutParams() - { - int buttonAreaHeight = (int)(mFullSize * fixedButtonRatio); - // add a button into the bottom of the circle layout - mParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,buttonAreaHeight); - mParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 1); - mBtnContent.setLayoutParams(mParams); - } - - /** - * locates the circle on the correct position. The correct position depends on phone model. - *

- * @author sujin.cho - */ - private void getTemplateDiameter(Context context) - { - if(context != null) { - if (!QCircleFeature.isQuickCircleAvailable(context)) { - Log.i(TAG, "Quick Circle case is not available"); - return; - } - // circle size - int id = context.getResources().getIdentifier( - "config_circle_diameter", "dimen", "com.lge.internal"); - mFullSize = context.getResources().getDimensionPixelSize(id); - } - else - { - - } - } + /** + * Adds this to the template. + * + * @param parent + * @author sujin.cho + */ + @Override + protected void addTo(RelativeLayout parent, RelativeLayout content) { + if ((mBtnContent != null) && (parent != null)) { + setLayoutParams(); + parent.addView(mBtnContent); + adjustLayout(content); + } + } + + private void adjustLayout(RelativeLayout content) { + RelativeLayout.LayoutParams contentParams = (RelativeLayout.LayoutParams) content.getLayoutParams(); + contentParams.addRule(RelativeLayout.ABOVE, mBtnContent.getId()); + content.setLayoutParams(contentParams); + } + + /** + * sets layout parameters of the back button. + */ + private void setLayoutParams() { + int buttonAreaHeight = (int) (mFullSize * fixedButtonRatio); + // add a button into the bottom of the circle layout + mParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, buttonAreaHeight); + mParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 1); + mBtnContent.setLayoutParams(mParams); + } } diff --git a/designTemplate/src/main/java/com/lge/qcircle/template/QCircleDialog.java b/designTemplate/src/main/java/com/lge/qcircle/template/QCircleDialog.java index 0dff714..02b13a5 100644 --- a/designTemplate/src/main/java/com/lge/qcircle/template/QCircleDialog.java +++ b/designTemplate/src/main/java/com/lge/qcircle/template/QCircleDialog.java @@ -5,11 +5,11 @@ import android.graphics.Color; import android.graphics.drawable.Drawable; import android.view.View; +import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; -import com.lge.qcircle.template.QCircleTitle; /** * The {@code QCircleDialog} class provides a Dialog for Quick Circle.

@@ -20,241 +20,243 @@ * @author Yoav Sternberg */ public class QCircleDialog { - Activity activity; - QCircleTemplate activityTemplate; - // Dialog properties - String title; - String text; - String positiveButtonText; - String negativeButtonText; - Drawable image; - View.OnClickListener positiveButtonListener; - View.OnClickListener negativeButtonListener; - DialogMode mode; - View templateLayout; + Activity activity; + QCircleTemplate activityTemplate; + // Dialog properties + CharSequence title; + CharSequence text; + CharSequence positiveButtonText; + CharSequence negativeButtonText; + Drawable image; + View.OnClickListener positiveButtonListener; + View.OnClickListener negativeButtonListener; + DialogMode mode; + View templateLayout; - /** - * private constructor. - * - * @param builder - */ - private QCircleDialog(Builder builder) { - this.title = builder.title; - this.text = builder.text; - this.positiveButtonText = builder.positiveButtonText; - this.negativeButtonText = builder.negativeButtonText; - this.image = builder.image; - this.positiveButtonListener = builder.positiveButtonListener; - this.negativeButtonListener = builder.negativeButtonListener; - this.mode = builder.mode; - } + /** + * private constructor. + * + * @param builder The builder + */ + private QCircleDialog(Builder builder) { + this.title = builder.title; + this.text = builder.text; + this.positiveButtonText = builder.positiveButtonText; + this.negativeButtonText = builder.negativeButtonText; + this.image = builder.image; + this.positiveButtonListener = builder.positiveButtonListener; + this.negativeButtonListener = builder.negativeButtonListener; + this.mode = builder.mode; + } - /** - * The {@code QCircleDialog.Builder} class is a builder to create a Dialog for Quick Circle. - * - * @author Yoav Sternberg - */ - public static class Builder { - private String title = null; - private String text; - private String positiveButtonText; - private String negativeButtonText; - private Drawable image = null; - private View.OnClickListener positiveButtonListener; - private View.OnClickListener negativeButtonListener = null; - private DialogMode mode = DialogMode.Ok; + /** + * The {@code QCircleDialog.Builder} class is a builder to create a Dialog for Quick Circle. + * + * @author Yoav Sternberg + */ + public static class Builder { + private CharSequence title = null; + private CharSequence text; + private CharSequence positiveButtonText; + private CharSequence negativeButtonText; + private Drawable image = null; + private View.OnClickListener positiveButtonListener; + private View.OnClickListener negativeButtonListener = null; + private DialogMode mode = DialogMode.Ok; - //sujin.cho - private QCircleTitle mTitle = null; + /** + * sets title of the Dialog.

+ * + * @param title text of the title. It will be displayed on the top of the dialog. + * @return a Builder with title text + */ + public Builder setTitle(CharSequence title) { + this.title = title; + return this; + } - /** - * sets title of the Dialog.

- * - * @param title text of the title. It will be displayed on the top of the dialog. - * @return a Builder with title text - */ - public Builder setTitle(String title) { - this.title = title; - return this; - } + /** + * sets main text of the dialog.

+ * + * @param text main text. It will be displayed on the middle of the dialog. + * @return a Builder with main text + */ + public Builder setText(CharSequence text) { + this.text = text; + return this; + } - /** - * sets main text of the dialog.

- * - * @param text main text. It will be displayed on the middle of the dialog. - * @return a Builder with main text - */ - public Builder setText(String text) { - this.text = text; - return this; - } + /** + * sets main image of the dialog.

+ * + * @param image main image as a Drawable. It will be displayed on the bottom of the main text. + * @return a Builder with main image + */ + public Builder setImage(Drawable image) { + this.image = image; + return this; + } - /** - * sets main image of the dialog.

- * - * @param image main image as a Drawable. It will be displayed on the bottom of the main text. - * @return a Builder with main image - */ - public Builder setImage(Drawable image) { - this.image = image; - return this; - } + /** + * sets a listener for positive button. + * + * @param positiveButtonListener lister to set + * @return a Builder with the listener for positive button + */ + public Builder setPositiveButtonListener(View.OnClickListener positiveButtonListener) { + this.positiveButtonListener = positiveButtonListener; + return this; + } - /** - * sets a listener for positive button. - * - * @param positiveButtonListener lister to set - * @return a Builder with the listener for positive button - */ - public Builder setPositiveButtonListener(View.OnClickListener positiveButtonListener) { - this.positiveButtonListener = positiveButtonListener; - return this; - } + /** + * sets a listener for negative button. + * + * @param negativeButtonListener listener to set + * @return a Builder with the listener for negative button + */ + public Builder setNegativeButtonListener(View.OnClickListener negativeButtonListener) { + this.negativeButtonListener = negativeButtonListener; + return this; + } - /** - * sets a listener for negative button. - * - * @param negativeButtonListener listener to set - * @return a Builder with the listener for negative button - */ - public Builder setNegativeButtonListener(View.OnClickListener negativeButtonListener) { - this.negativeButtonListener = negativeButtonListener; - return this; - } + /** + * sets a mode fot eh dialog. + * + * @param mode dialog mode. see {@link com.lge.qcircle.template.QCircleDialog.DialogMode}. + * @return a Builder with the dialog mode. + */ + public Builder setMode(DialogMode mode) { + this.mode = mode; + return this; + } - /** - * sets a mode fot eh dialog. - * - * @param mode dialog mode. see {@link com.lge.qcircle.template.QCircleDialog.DialogMode}. - * @return a Builder with the dialog mode. - */ - public Builder setMode(DialogMode mode) { - this.mode = mode; - return this; - } + /** + * sets a text for positive button. + * + * @param positiveButtonText text for positive button + */ + public Builder setPositiveButtonText(CharSequence positiveButtonText) { + this.positiveButtonText = positiveButtonText; + return this; + } - /** - * sets a text for positive button. - * - * @param positiveButtonText text for positive button - */ - public void setPositiveButtonText(String positiveButtonText) { - this.positiveButtonText = positiveButtonText; - } + /** + * sets a text for negative button. + * + * @param negativeButtonText text for negative button + */ + public Builder setNegativeButtonText(CharSequence negativeButtonText) { + this.negativeButtonText = negativeButtonText; + return this; + } - /** - * sets a text for negative button. - * - * @param negativeButtonText text for negative button - */ - public void setNegativeButtonText(String negativeButtonText) { - this.negativeButtonText = negativeButtonText; - } + /** + * creates a dialog.

+ * It should be called when setting of the dialog is done by the Builder. + * + * @return a dialog created by the Builder. + */ + public QCircleDialog create() { + return new QCircleDialog(this); + } + } - /** - * creates a dialog.

- * It should be called when setting of the dialog is done by the Builder. - * - * @return a dialog created by the Builder. - */ - public QCircleDialog create() { - return new QCircleDialog(this); - } - } - - /** - * Show the dialog - * - * @param activity The activity - * @param activityTemplate The template that the activity uses - */ - public void show(final Activity activity, QCircleTemplate activityTemplate) { - this.activity = activity; - this.activityTemplate = activityTemplate; - RelativeLayout layout = (RelativeLayout) activityTemplate.getLayoutById(TemplateTag.CONTENT).getParent(); - final QCircleTemplate template = new QCircleTemplate(activity); - //template.setTitle(title == null ? "" : title, Color.WHITE, activity.getResources().getColor( - // mode == DialogMode.Error ? R.color.dialog_title_background_color_error : R.color.dialog_title_background_color_regular)); - //template.setTitleTextSize(17); - RelativeLayout dialogLayout = (RelativeLayout) activity.getLayoutInflater() - .inflate(mode == DialogMode.YesNo ? R.layout.qcircle_dialog_layout_yes_no : R.layout.qcircle_dialog_layout, layout, false); - if (text != null) { - ((TextView) dialogLayout.findViewById(R.id.text)).setText(text); - } - if (image != null) { - ((ImageView) dialogLayout.findViewById(R.id.image)).setImageDrawable(image); - } else dialogLayout.findViewById(R.id.image).setVisibility(View.GONE); - switch (mode) { - case YesNo: - Button negativeButton = (Button) dialogLayout.findViewById(R.id.negative); - if (negativeButtonText != null) { - negativeButton.setText(negativeButtonText); - } - negativeButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (negativeButtonListener != null) negativeButtonListener.onClick(v); - hide(); - } - }); - case Ok: - Button positiveButton = (Button) dialogLayout.findViewById(R.id.positive); - if (positiveButtonText != null) { - positiveButton.setText(positiveButtonText); - } - positiveButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (positiveButtonListener != null) positiveButtonListener.onClick(v); - hide(); - } - }); - break; - case Error: - @SuppressLint("CutPasteId") - Button errorButton = (Button) dialogLayout.findViewById(R.id.positive); - if (negativeButtonText != null) { - errorButton.setText(negativeButtonText); - } - errorButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (negativeButtonListener != null) negativeButtonListener.onClick(v); + /** + * Show the dialog + * + * @param activity The activity + * @param activityTemplate The template that the activity uses + */ + public void show(final Activity activity, QCircleTemplate activityTemplate) { + this.activity = activity; + this.activityTemplate = activityTemplate; + ViewGroup layout = (ViewGroup) activityTemplate.getView().getParent(); + final QCircleTemplate template = new QCircleTemplate(activity, TemplateType.CIRCLE_EMPTY); + QCircleTitle qCircleTitle = new QCircleTitle(activity, title == null ? "" : title, Color.WHITE, + activity.getResources().getColor(mode == DialogMode.Error ? R.color.dialog_title_background_color_error : R.color.dialog_title_background_color_regular)); + qCircleTitle.setTextSize(17f); + template.addElement(qCircleTitle); + RelativeLayout dialogLayout = (RelativeLayout) activity.getLayoutInflater() + .inflate(mode == DialogMode.YesNo ? R.layout.qcircle_dialog_layout_yes_no : R.layout.qcircle_dialog_layout, layout, false); + if (text != null) { + ((TextView) dialogLayout.findViewById(R.id.text)).setText(text); + } + if (image != null) { + ((ImageView) dialogLayout.findViewById(R.id.image)).setImageDrawable(image); + } else dialogLayout.findViewById(R.id.image).setVisibility(View.GONE); + switch (mode) { + case YesNo: + Button negativeButton = (Button) dialogLayout.findViewById(R.id.negative); + if (negativeButtonText != null) { + negativeButton.setText(negativeButtonText); + } + negativeButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (negativeButtonListener != null) negativeButtonListener.onClick(v); + hide(); + } + }); + case Ok: + Button positiveButton = (Button) dialogLayout.findViewById(R.id.positive); + if (positiveButtonText != null) { + positiveButton.setText(positiveButtonText); + } + positiveButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (positiveButtonListener != null) positiveButtonListener.onClick(v); + hide(); + } + }); + break; + case Error: + @SuppressLint("CutPasteId") + Button errorButton = (Button) dialogLayout.findViewById(R.id.positive); + if (negativeButtonText != null) { + errorButton.setText(negativeButtonText); + } + errorButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (negativeButtonListener != null) negativeButtonListener.onClick(v); // template.unregisterReceiver(); - activity.finish(); - } - }); - break; + activity.finish(); + } + }); + break; - } - template.getLayoutById(TemplateTag.CONTENT).addView(dialogLayout); - layout.addView(templateLayout = template.getView()); - } + } + template.getLayoutById(TemplateTag.CONTENT).addView(dialogLayout); + activityTemplate.getView().setVisibility(View.GONE); + layout.addView(templateLayout = template.getView()); + } - /** - * hides the dialog. - */ - public void hide() { - ((RelativeLayout) activityTemplate.getLayoutById(TemplateTag.CONTENT).getParent()).removeView(templateLayout); - templateLayout = null; - } + /** + * hides the dialog. + */ + public void hide() { + ((ViewGroup) activityTemplate.getView().getParent()).removeView(templateLayout); + activityTemplate.getView().setVisibility(View.VISIBLE); + templateLayout = null; + } - /** - * The {@code DialogMode} enumerates modes which are - * supported by {@link com.lge.qcircle.template.QCircleDialog}. - */ - public enum DialogMode { - /** - * A dialog with yes and no buttons. - */ - YesNo, - /** - * A dialog with ok button only. - */ - Ok, - /** - * An error dialog. Shows only back button, which finish the activity. - */ - Error - } + /** + * The {@code DialogMode} enumerates modes which are + * supported by {@link com.lge.qcircle.template.QCircleDialog}. + */ + public enum DialogMode { + /** + * A dialog with yes and no buttons. + */ + YesNo, + /** + * A dialog with ok button only. + */ + Ok, + /** + * An error dialog. Shows only back button, which finish the activity. + */ + Error + } } diff --git a/designTemplate/src/main/java/com/lge/qcircle/template/QCircleTemplate.java b/designTemplate/src/main/java/com/lge/qcircle/template/QCircleTemplate.java index 7f5fdb4..bd143be 100644 --- a/designTemplate/src/main/java/com/lge/qcircle/template/QCircleTemplate.java +++ b/designTemplate/src/main/java/com/lge/qcircle/template/QCircleTemplate.java @@ -21,20 +21,22 @@ import com.lge.qcircle.utils.QCircleFeature; +import java.util.concurrent.Callable; + /** * The {@code QCircleTemplate} class provides design templates for LG QuickCircle. - *

+ *

* There are 5 templates:
*

    *
  • empty content
  • *
  • content with a horizontal sidebar
  • *
  • content with a vertical sidebar
  • - *
  • content with 2 topbars
  • + *
  • content with 2 top bars
  • *
  • content with 2 sidebars
  • *
* In order to get the layout, see {@link com.lge.qcircle.template.TemplateType}.
* In addition, you can add a title or a back button into each layout described above. - *

+ *

* This class supports APIs for setting layout, changing attributes of Views in the layout, and * setting fullscreen intent. * @@ -43,428 +45,431 @@ */ public class QCircleTemplate { - // constants - protected static final String TAG = "QCircleTemplate"; - protected static final int EXTRA_ACCESSORY_COVER_OPENED = 0; - protected static final int EXTRA_ACCESSORY_COVER_CLOSED = 1; - protected static final String EXTRA_ACCESSORY_COVER_STATE = "com.lge.intent.extra.ACCESSORY_COVER_STATE"; - protected static final String ACTION_ACCESSORY_COVER_EVENT = "com.lge.android.intent.action.ACCESSORY_COVER_EVENT"; - + // constants + protected static final String TAG = "QCircleTemplate"; + protected static final int EXTRA_ACCESSORY_COVER_OPENED = 0; + protected static final int EXTRA_ACCESSORY_COVER_CLOSED = 1; + protected static final String EXTRA_ACCESSORY_COVER_STATE = "com.lge.intent.extra.ACCESSORY_COVER_STATE"; + protected static final String ACTION_ACCESSORY_COVER_EVENT = "com.lge.android.intent.action.ACCESSORY_COVER_EVENT"; // strings for special devices - protected static final String DEVICE_G3 = "g3"; - protected static final String DEVICE_T6 = "tiger6"; - - // environments - protected Context mContext = null; - protected BroadcastReceiver mReceiver = null; - protected Intent mFullscreenIntent = null; - protected IntentCreatorAsync mAsyncCreator = null; - - // Views - protected TemplateType mLayoutType = TemplateType.CIRCLE_EMPTY; - protected FrameLayout mRootLayout = null; - protected RelativeLayout mCircleLayout = null; - protected RelativeLayout mContent = null; - protected QCircleBackButton mBackButton = null; - protected QCircleTitle mTitle = null; - - // layout values + protected static final String DEVICE_G3 = "g3"; + protected static final String DEVICE_T6 = "tiger6"; + + // environments + protected Context mContext = null; + protected BroadcastReceiver mReceiver = null; + protected Intent mFullscreenIntent = null; + protected Callable mAsyncCreator = null; + protected boolean mShouldSetLayoutParams = true; + + // Views + protected TemplateType mLayoutType = TemplateType.CIRCLE_EMPTY; + protected FrameLayout mRootLayout = null; + protected RelativeLayout mCircleLayout = null; + protected RelativeLayout mContent = null; + protected QCircleBackButton mBackButton = null; + protected QCircleTitle mTitle = null; + + // layout values private static int mFullSize = 0; // circle diameter private static int mTopOffset = 0; // top offset of circle - private static int mYpos = 0; - - /** - @deprecated - */ - private final float fixedButtonRatio = 0.23f; // Button height ratio - /** - @deprecated - */ - private final float fixedTitleRatio = 0.23f; // Title height ratio - - - /** - * creates a template with an empty content. - * - * @param context Activity which has the template.
- * It should be an Activity because the template will close the Activity when the - * cover is opened.
- * If it is null, other APIs will not work and report errors. - */ - public QCircleTemplate(Context context) { - this(context, TemplateType.CIRCLE_EMPTY); - } - - /** - * creates a template with the given template type. - * - * @param context Activity which has the template.
- * It should be an Activity because the template will close the Activity when the - * cover is opened.
- * If it is null, other APIs will not work and report errors. - * @param type type of the design template you want to use.
- * If it is null, an empty content template will be used. - * @see com.lge.qcircle.template.TemplateType - */ - public QCircleTemplate(Context context, TemplateType type) { - mContext = context; - if (type == null) - type = TemplateType.CIRCLE_EMPTY; - setTemplateType(type); // set layout style - } - - /** - * creates a template with the given layout. - * - * @param context Activity which has the template.
- * It should be an Activity because the template will close the Activity when the - * cover is opened.
- * If it is null, other APIs will not work and report errors. - * @param templateId ID of the layout to use - */ - public QCircleTemplate(Context context, int templateId) { - mContext = context; - if (templateId <= 0) { - templateId = R.layout.qcircle_empty; - } - loadCustomTemplate(templateId); - } - - /** - * sets the intent running in fullscreen when the cover is opened. - * - * @param intent intent to run the fullscreen Activity.
- * If it is null, nothing will be happened when the cover is opened.
- * You can set this as null when you clean up the existing intent. - */ - public void setFullscreenIntent(Intent intent) { - if (intent == null) { - Log.w(TAG, "The given intent is null"); - } - mFullscreenIntent = intent; - mAsyncCreator = null; - } - - /** - * sets the intent running in fullscreen when the cover is opened. - * - * @param creatorAsync will be called only when the intent is needed. - */ - public void setFullscreenIntent(IntentCreatorAsync creatorAsync) { - mFullscreenIntent = null; - mAsyncCreator = creatorAsync; - } - - /** - * gets the root view of the template layout. - *

- * - * @return root view of the layout. - */ - public View getView() { - setQuickCircleWindowParam(); - return mRootLayout; - } - - /** - * @deprecated - * sets a title. - *

- * It creates a title bar on the top of the layout. - *

- * Note that this method does not create a title bar when the title bar already exists. It - * changes the text of the existing title bar. - * - * @param title text for the title.
- * If it is null, no title text will be shown but the title bar will occupy some - * space. - */ - public void setTitle(String title) { - setTitle(title, fixedTitleRatio); - } - - /** - * @deprecated - * sets a title with the given height ratio. - *

- * It creates a title bar on the top of the layout. The height of the title bar depends on - * {@code heightRatio}. - *

- * Note that this method does not create a title bar when the title bar already exists. It - * changes the text and the height of the existing title bar. - * - * @param title text for the title.
- * If it is null, no title text will be shown but the title bar will occupy some - * space. - * @param heightRatio ratio of the title bar.
- * If it is less or equal to 0, the height ratio of the title bar will be 0.2 of - * QuickCircle diameter. - */ - public void setTitle(String title, float heightRatio) { - setTitle(title, heightRatio, Color.BLACK, Color.TRANSPARENT); - } - - /** - * @deprecated - * sets a title with the given height ratio and the given title color and background color. - *

- * It creates a title bar on the top of the layout. The height of the title bar depends on - * {@code heightRatio}. - *

- * Note that this method does not create a title bar when the title bar already exists. It - * changes the text and the height of the existing title bar. - * - * @param title text for the title.
- * If it is null, no title text will be shown but the title bar will occupy some - * space. - * @param heightRatio ratio of the title bar.
- * If it is less or equal to 0, the height ratio of the title bar will be 0.2 of - * QuickCircle diameter. - * @param textColor The color of the title - * @param backgroundColor The background color of the title - */ - public void setTitle(String title, float heightRatio, int textColor, int backgroundColor) { - if (mTitle == null) { - if (mContext != null) - mTitle = new QCircleTitle(mContext, title, textColor, backgroundColor); - else { - Log.w(TAG, "Cannot create the title: context is null"); - return; - } - addTitleView(mTitle, heightRatio); - } else { // change the string only - mTitle.setText(title); - changeTitleViewHeight(heightRatio); - } - } - - - /** - * @deprecated - * sets a title with the default height ratio and the given title color and background color. - *

- * It creates a title bar on the top of the layout. The height of the title bar depends on - * {@code heightRatio}. - *

- * Note that this method does not create a title bar when the title bar already exists. It - * changes the text and the height of the existing title bar. - * - * @param title text for the title.
- * If it is null, no title text will be shown but the title bar will occupy some - * space. - * @param textColor The color of the title - * @param backgroundColor The background color of the title - */ - public void setTitle(String title, int textColor, int backgroundColor) { - setTitle(title, fixedTitleRatio, textColor, backgroundColor); - } - - - /** - * @deprecated - * sets a title as the given view with the given height ratio. - *

- * It creates a title bar on the top of the layout. The content of the title bar is - * {@code titleView} and the height of the title bar depends on {@code heightRatio}. - *

- * Note that this method does not create a title bar when the title bar already exists. It - * changes the content and the view of the existing title bar. - * - * @param titleView View to be a title - * @param heightRatio ratio of the title bar.
- * If it is less or equal to 0, the height ratio of the title bar will be 0.2 of - * QuickCircle diameter. - */ - public void setTitle(View titleView, float heightRatio) { - if (mTitle == null) { // create a Title - if (mContext != null) - mTitle = new QCircleTitle(mContext, titleView); - else { - Log.w(TAG, "Cannot create the title: context is null"); - return; - } - addTitleView(mTitle, heightRatio); - } else { - Log.i(TAG, "Title view is updated by user."); - if (!mTitle.setView(titleView)) { - Log.w(TAG, "Cannot set the view as a title."); - } else { - changeTitleViewHeight(heightRatio); - } - } - } - - - /** - * @deprecated - * sets a back button. - *

- * It creates a back button on the bottom of the layout. - *

- * You do not need to implement an {@code onClickListener} for the button, because it already - * has one.
- * Note that this method does not create a button when the button already exists. - */ - public void setBackButton() { - setBackButton(null); - } - - - /** + + /** * @deprecated - * sets a back button with callback. - *

- * It creates a back button on the bottom of the layout. - *

- * You do not need to implement an {@code onClickListener} for the button, because it already - * has one.
- * Note that this method does not create a button when the button already exists. - * @param onClickListener Callback for back button. - * should be used for closing objects, like camera - */ - public void setBackButton(View.OnClickListener onClickListener) { - if (mBackButton == null) { - if (mContext != null) - mBackButton = new QCircleBackButton(mContext, (int)(mFullSize * fixedButtonRatio), onClickListener); - else { - Log.e(TAG, "Cannot create the back button: context is null"); - return; - } - addBackButtonView(mBackButton); - } - } - - - /** + */ + private final float fixedButtonRatio = 0.23f; // Button height ratio + /** * @deprecated - * Set the theme to the back button. Default is light. - * @param isDark Is dark theme + */ + private final float fixedTitleRatio = 0.23f; // Title height ratio + + /** + * creates a template with an empty content. + * + * @param context Activity which has the template.
+ * It should be an Activity because the template will close the Activity when the + * cover is opened.
+ * If it is null, other APIs will not work and report errors. + */ + public QCircleTemplate(Context context) { + this(context, TemplateType.CIRCLE_EMPTY); + } + + /** + * creates a template with the given template type. + * + * @param context Activity which has the template.
+ * It should be an Activity because the template will close the Activity when the + * cover is opened.
+ * If it is null, other APIs will not work and report errors. + * @param type type of the design template you want to use.
+ * If it is null, an empty content template will be used. + * @see com.lge.qcircle.template.TemplateType + */ + public QCircleTemplate(Context context, TemplateType type) { + this(context, type, true); + } + + /** + * creates a template with the given layout. + * + * @param context Activity which has the template.
+ * It should be an Activity because the template will close the Activity when the + * cover is opened.
+ * If it is null, other APIs will not work and report errors. + * @param templateId ID of the layout to use + */ + public QCircleTemplate(Context context, int templateId) { + mContext = context; + if (templateId <= 0) { + templateId = R.layout.qcircle_empty; + } + loadCustomTemplate(templateId); + } + + /** + * Create a template for dialog. + * + * @param context Activity which has the template. + */ + /* package */ QCircleTemplate(Context context, TemplateType type, boolean shouldSetLayoutParams) { + mContext = context; + mShouldSetLayoutParams = shouldSetLayoutParams; + if (type == null) + type = TemplateType.CIRCLE_EMPTY; + setTemplateType(type); // set layout style + } + + /** + * sets the intent running in fullscreen when the cover is opened. + * + * @param intent intent to run the fullscreen Activity.
+ * If it is null, nothing will be happened when the cover is opened.
+ * You can set this as null when you clean up the existing intent. + */ + public void setFullscreenIntent(Intent intent) { + if (intent == null) { + Log.w(TAG, "The given intent is null"); + } + mFullscreenIntent = intent; + mAsyncCreator = null; + } + + /** + * sets the intent running in fullscreen when the cover is opened. + * + * @param creatorAsync will be called only when the intent is needed. + */ + @Deprecated + public void setFullscreenIntent(final IntentCreatorAsync creatorAsync) { + mFullscreenIntent = null; + mAsyncCreator = new Callable() { + @Override + public Intent call() throws Exception { + return creatorAsync.getIntent(); + } + }; + } + + /** + * sets the intent running in fullscreen when the cover is opened. + * + * @param creatorAsync will be called only when the intent is needed. + */ + @Deprecated + public void setFullscreenIntent(Callable creatorAsync) { + mFullscreenIntent = null; + mAsyncCreator = creatorAsync; + } + + /** + * gets the root view of the template layout. + *

+ * + * @return root view of the layout. + */ + public View getView() { + setQuickCircleWindowParam(); + return mRootLayout; + } + + /** + * @param title text for the title.
+ * If it is null, no title text will be shown but the title bar will occupy some + * space. + * @deprecated sets a title. + *

+ * It creates a title bar on the top of the layout. + *

+ * Note that this method does not create a title bar when the title bar already exists. It + * changes the text of the existing title bar. + */ + public void setTitle(String title) { + setTitle(title, fixedTitleRatio); + } + + /** + * @param title text for the title.
+ * If it is null, no title text will be shown but the title bar will occupy some + * space. + * @param heightRatio ratio of the title bar.
+ * If it is less or equal to 0, the height ratio of the title bar will be 0.2 of + * QuickCircle diameter. + * @deprecated sets a title with the given height ratio. + *

+ * It creates a title bar on the top of the layout. The height of the title bar depends on + * {@code heightRatio}. + *

+ * Note that this method does not create a title bar when the title bar already exists. It + * changes the text and the height of the existing title bar. + */ + public void setTitle(String title, float heightRatio) { + setTitle(title, heightRatio, Color.BLACK, Color.TRANSPARENT); + } + + /** + * @param title text for the title.
+ * If it is null, no title text will be shown but the title bar will occupy some + * space. + * @param heightRatio ratio of the title bar.
+ * If it is less or equal to 0, the height ratio of the title bar will be 0.2 of + * QuickCircle diameter. + * @param textColor The color of the title + * @param backgroundColor The background color of the title + * @deprecated sets a title with the given height ratio and the given title color and background color. + *

+ * It creates a title bar on the top of the layout. The height of the title bar depends on + * {@code heightRatio}. + *

+ * Note that this method does not create a title bar when the title bar already exists. It + * changes the text and the height of the existing title bar. + */ + public void setTitle(String title, float heightRatio, int textColor, int backgroundColor) { + if (mTitle == null) { + if (mContext != null) + mTitle = new QCircleTitle(mContext, title, textColor, backgroundColor); + else { + Log.w(TAG, "Cannot create the title: context is null"); + return; + } + addTitleView(mTitle, heightRatio); + } else { // change the string only + mTitle.setText(title); + changeTitleViewHeight(heightRatio); + } + } + + /** + * @param title text for the title.
+ * If it is null, no title text will be shown but the title bar will occupy some + * space. + * @param textColor The color of the title + * @param backgroundColor The background color of the title + * @deprecated sets a title with the default height ratio and the given title color and background color. + *

+ * It creates a title bar on the top of the layout. The height of the title bar depends on + * {@code heightRatio}. + *

+ * Note that this method does not create a title bar when the title bar already exists. It + * changes the text and the height of the existing title bar. + */ + public void setTitle(String title, int textColor, int backgroundColor) { + setTitle(title, fixedTitleRatio, textColor, backgroundColor); + } + + /** + * @param titleView View to be a title + * @param heightRatio ratio of the title bar.
+ * If it is less or equal to 0, the height ratio of the title bar will be 0.2 of + * QuickCircle diameter. + * @deprecated sets a title as the given view with the given height ratio. + *

+ * It creates a title bar on the top of the layout. The content of the title bar is + * {@code titleView} and the height of the title bar depends on {@code heightRatio}. + *

+ * Note that this method does not create a title bar when the title bar already exists. It + * changes the content and the view of the existing title bar. + */ + public void setTitle(View titleView, float heightRatio) { + if (mTitle == null) { // create a Title + if (mContext != null) + mTitle = new QCircleTitle(mContext, titleView); + else { + Log.w(TAG, "Cannot create the title: context is null"); + return; + } + addTitleView(mTitle, heightRatio); + } else { + Log.i(TAG, "Title view is updated by user."); + if (!mTitle.setView(titleView)) { + Log.w(TAG, "Cannot set the view as a title."); + } else { + changeTitleViewHeight(heightRatio); + } + } + } + + /** + * @deprecated sets a back button. + *

+ * It creates a back button on the bottom of the layout. + *

+ * You do not need to implement an {@code onClickListener} for the button, because it already + * has one.
+ * Note that this method does not create a button when the button already exists. + */ + public void setBackButton() { + setBackButton(null); + } + + /** + * @param onClickListener Callback for back button. + * should be used for closing objects, like camera + * @deprecated sets a back button with callback. + *

+ * It creates a back button on the bottom of the layout. + *

+ * You do not need to implement an {@code onClickListener} for the button, because it already + * has one.
+ * Note that this method does not create a button when the button already exists. + */ + public void setBackButton(View.OnClickListener onClickListener) { + if (mBackButton == null) { + if (mContext != null) + mBackButton = new QCircleBackButton(mContext, (int) (mFullSize * fixedButtonRatio), onClickListener); + else { + Log.e(TAG, "Cannot create the back button: context is null"); + return; + } + addBackButtonView(mBackButton); + } + } + + /** + * @param isDark Is dark theme * @author Yoav Sternberg - */ - public void setBackButtonTheme(boolean isDark) { - if (mBackButton != null) { - mBackButton.isDark(isDark); - } - } - - /** - * gets a layout with the given id. - *

- * This method is useful when you want to add or modify Views of the template.
- * Every content or sidebar is a {@code RelativeLayout}. - * - * @param id id of the layout to retrieve. Use {@link com.lge.qcircle.template.TemplateTag}.
- * @return a {@code RelativeLayout} whose ID is identical to {@code id}.
- * or null if there is no View with the given ID. - */ - public RelativeLayout getLayoutById(int id) { - RelativeLayout result = null; - if (mContent != null && id > 0) { - result = (RelativeLayout) mContent.findViewById(id); - } - return result; - } - - /** - * changes the ratio of the first sidebar. - *

- * Some design templates have sidebars which is re-sizable. Note that only the first sidebar can - * be re-sized even if the template has more than 1 sidebars.
- * This method changes the size of the first sidebar with the ratio comparing to the full - * content layout.
- * If you add a title bar or a back button after calling this method, the size of the sidebar - * will not change. Therefore some UI components might be hidden by the title bar or a back - * button.
- * Call this method after adding a title bar and a back button to prevent the situation. - * - * @param weight ratio of the first sidebar.
- * The valid ranage is (0,1). (cannot be 0 or 1). - * @return true, if the size is changed successfully or
- * false, otherwise. - */ - public boolean setSidebarRatio(float weight) { - boolean result = false; - if (mContent != null) { // check validation - if (weight < 0 || weight > 1) { // check validation - Log.i(TAG, "content rate should be in range (0,1): current = " + weight); - } else { - // get side1 - View firstContent = (View) mContent.findViewById(R.id.side1); - if (mLayoutType == TemplateType.CIRCLE_COMPLEX) { - firstContent = (View) firstContent.getParent(); - } - if (firstContent != null) { - int parentSize = mFullSize; - if (mLayoutType == TemplateType.CIRCLE_VERTICAL) { // adjust width - LayoutParams params = firstContent.getLayoutParams(); - params.width = (int) (parentSize * weight); - firstContent.setLayoutParams(params); - - } else if (mLayoutType == TemplateType.CIRCLE_HORIZONTAL // adjust height - || mLayoutType == TemplateType.CIRCLE_COMPLEX) { - parentSize = (int) (mFullSize * (1 - 0.2 * ((mBackButton != null ? 1 : 0) + (mTitle != null ? 1 - : 0)))); - LayoutParams params = firstContent.getLayoutParams(); - params.height = (int) (parentSize * weight); - firstContent.setLayoutParams(params); - } - result = true; - } else - Log.w(TAG, "There is no first sidebar in this layout"); - } - } else - Log.w(TAG, "No content layout. please set default content layout"); - return result; - } - - /** - * @deprecated - * sets the background of the template as the given image. - *

- * The background affects all the layouts including a title bar and a back button. - * - * @param image background image - * @param overwiteButtonArea flag for clear background of the back button if it exists.
- * The default background of a back button is light gray. You should clear the - * background color of a back button when you want to use full-layout background.
- * Set this flag in that case. - * @see #setBackgroundColor(int, boolean) - */ - public void setBackgroundDrawable(Drawable image, boolean overwiteButtonArea) { - if (mCircleLayout != null) - mCircleLayout.setBackground(image); - if (overwiteButtonArea && mBackButton != null) - mBackButton.setBackgroundTransparent(); - // if (overwiteButtonArea && mTitle != null) - // mTitle.setBackgroundTransparent(); - } + * @deprecated Set the theme to the back button. Default is light. + */ + public void setBackButtonTheme(boolean isDark) { + if (mBackButton != null) { + mBackButton.isDark(isDark); + } + } /** - * sets the background of the template as the given image. - *

- * The background affects all the layouts including a title bar and a back button. + * gets a layout with the given id. + *

+ * This method is useful when you want to add or modify Views of the template.
+ * Every content or sidebar is a {@code RelativeLayout}. * + * @param id id of the layout to retrieve. Use {@link com.lge.qcircle.template.TemplateTag}.
+ * @return a {@code RelativeLayout} whose ID is identical to {@code id}.
+ * or null if there is no View with the given ID. + */ + public RelativeLayout getLayoutById(int id) { + RelativeLayout result = null; + if (mContent != null && id > 0) { + result = (RelativeLayout) mContent.findViewById(id); + } + return result; + } + + /** + * changes the ratio of the first sidebar. + *

+ * Some design templates have sidebars which is re-sizable. Note that only the first sidebar can + * be re-sized even if the template has more than 1 sidebars.
+ * This method changes the size of the first sidebar with the ratio comparing to the full + * content layout.
+ * If you add a title bar or a back button after calling this method, the size of the sidebar + * will not change. Therefore some UI components might be hidden by the title bar or a back + * button.
+ * Call this method after adding a title bar and a back button to prevent the situation. + * + * @param weight ratio of the first sidebar.
+ * The valid ranage is (0,1). (cannot be 0 or 1). + * @return true, if the size is changed successfully or
+ * false, otherwise. + */ + public boolean setSidebarRatio(float weight) { + boolean result = false; + if (mContent != null) { // check validation + if (weight < 0 || weight > 1) { // check validation + Log.i(TAG, "content rate should be in range (0,1): current = " + weight); + } else { + // get side1 + View firstContent = (View) mContent.findViewById(R.id.side1); + if (mLayoutType == TemplateType.CIRCLE_COMPLEX) { + firstContent = (View) firstContent.getParent(); + } + if (firstContent != null) { + int parentSize = mFullSize; + if (mLayoutType == TemplateType.CIRCLE_VERTICAL) { // adjust width + LayoutParams params = firstContent.getLayoutParams(); + params.width = (int) (parentSize * weight); + firstContent.setLayoutParams(params); + + } else if (mLayoutType == TemplateType.CIRCLE_HORIZONTAL // adjust height + || mLayoutType == TemplateType.CIRCLE_COMPLEX) { + parentSize = (int) (mFullSize * (1 - 0.2 * ((mBackButton != null ? 1 : 0) + (mTitle != null ? 1 + : 0)))); + LayoutParams params = firstContent.getLayoutParams(); + params.height = (int) (parentSize * weight); + firstContent.setLayoutParams(params); + } + result = true; + } else + Log.w(TAG, "There is no first sidebar in this layout"); + } + } else + Log.w(TAG, "No content layout. please set default content layout"); + return result; + } + + /** * @param image background image + * @param overwiteButtonArea flag for clear background of the back button if it exists.
+ * The default background of a back button is light gray. You should clear the + * background color of a back button when you want to use full-layout background.
+ * Set this flag in that case. * @see #setBackgroundColor(int, boolean) + * @deprecated sets the background of the template as the given image. + *

+ * The background affects all the layouts including a title bar and a back button. */ - public void setBackgroundDrawable(Drawable image) { + public void setBackgroundDrawable(Drawable image, boolean overwiteButtonArea) { if (mCircleLayout != null) mCircleLayout.setBackground(image); + if (overwiteButtonArea && mBackButton != null) + mBackButton.setBackgroundTransparent(); + // if (overwiteButtonArea && mTitle != null) + // mTitle.setBackgroundTransparent(); } - /** - * @deprecated - * sets the background of the template as the given color. - *

+ /** + * sets the background of the template as the given image. + *

* The background affects all the layouts including a title bar and a back button. * + * @param image background image + * @see #setBackgroundColor(int, boolean) + */ + public void setBackgroundDrawable(Drawable image) { + if (mCircleLayout != null) + mCircleLayout.setBackground(image); + } + + /** * @param color background color * @param overwiteButtonArea flag for clear background of the back button if it exists.
* The default background of a back button is light gray. You should clear the * background color of a back button when you want to use full-layout background.
* Set this flag in that case. * @see #setBackgroundDrawable(android.graphics.drawable.Drawable, boolean) + * @deprecated sets the background of the template as the given color. + *

+ * The background affects all the layouts including a title bar and a back button. */ public void setBackgroundColor(int color, boolean overwiteButtonArea) { if (mCircleLayout != null) @@ -475,10 +480,10 @@ public void setBackgroundColor(int color, boolean overwiteButtonArea) { /** * sets the background of the template as the given color. - *

+ *

* The background affects all the layouts including a title bar and a back button. * - * @param color background color + * @param color background color * @see #setBackgroundDrawable(android.graphics.drawable.Drawable, boolean) */ public void setBackgroundColor(int color) { @@ -486,252 +491,230 @@ public void setBackgroundColor(int color) { mCircleLayout.setBackgroundColor(color); } + /** + * @param size font size in pixel + * @deprecated sets the font size of the title. + *

+ */ + public void setTitleTextSize(float size) { + if (mTitle != null) { + mTitle.setTextSize(size); + } + } - /** - * @deprecated - * sets the font size of the title. - *

- * - * @param size font size in pixel - */ - public void setTitleTextSize(float size) { - if (mTitle != null) { - mTitle.setTextSize(size); - } - } - - /** - * initializes the layout of the circle window. - *

- * It loads a template layout from the xml file and retrieves the root view (actually a - * {@code FrameLayout} and the content view(a {@code RelativeLayout}). - * - * @param layoutView View that represents a layout. It should be a root view of the layout.
- * If it is null, setting layout will fail. - */ - private void initLayout(View layoutView) { - if (layoutView != null) { - mRootLayout = (FrameLayout) layoutView.findViewById(R.id.root); - mCircleLayout = (RelativeLayout) layoutView.findViewById(R.id.circlelayout); - mContent = (RelativeLayout) layoutView.findViewById(R.id.content); - - } else { - Log.e(TAG, "Cannot set the layout: root view is null"); - } - } + /** + * initializes the layout of the circle window. + *

+ * It loads a template layout from the xml file and retrieves the root view (actually a + * {@code FrameLayout} and the content view(a {@code RelativeLayout}). + * + * @param layoutView View that represents a layout. It should be a root view of the layout.
+ * If it is null, setting layout will fail. + */ + private void initLayout(View layoutView) { + if (layoutView != null) { + mRootLayout = (FrameLayout) layoutView.findViewById(R.id.root); + mCircleLayout = (RelativeLayout) layoutView.findViewById(R.id.circlelayout); + mContent = (RelativeLayout) layoutView.findViewById(R.id.content); + + } else { + Log.e(TAG, "Cannot set the layout: root view is null"); + } + } /** - * @deprecated - * changes the height of the title.

- * If there is no title bar on the layout, no happens. * @param heightRatio ratio of the title bar. + * @deprecated changes the height of the title.

+ * If there is no title bar on the layout, no happens. */ - private void changeTitleViewHeight(float heightRatio) { - if (mTitle != null) { - if (heightRatio <= 0) // adjust the height - heightRatio = fixedTitleRatio; - int titleAreaHeight = (int) (mFullSize * heightRatio); - // add a title into the top of the circle layout - RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( - LayoutParams.MATCH_PARENT, titleAreaHeight); - params.addRule(RelativeLayout.ALIGN_PARENT_TOP, 1); - mTitle.getView().setLayoutParams(params); - adjustContentLayout(); - } - } - - - /** - * @deprecated - * adds a title view to the layout. - *

- * It is called by {@link #setTitle(String)} to adjust the circle layout. The title view is - * added on the top of the layout and the content window will be on the below of the title view. - * - * @param titleView title view to be added.
- * If it is null, the circle layout will not change. - * @param heightRatio ratio of the title bar.
- * If it is less or equal to 0, the height ratio of the title bar will be 0.2 of - * QuickCircle diameter. - */ - private void addTitleView(QCircleTitle titleView, float heightRatio) { - if (mCircleLayout != null) { - if (heightRatio <= 0) // adjust the height - heightRatio = fixedTitleRatio; - int titleAreaHeight = (int) (mFullSize * heightRatio); - // add a title into the top of the circle layout - RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( - LayoutParams.MATCH_PARENT, titleAreaHeight); - params.addRule(RelativeLayout.ALIGN_PARENT_TOP, 1); - mCircleLayout.addView(titleView.getView(), 0, params); - adjustContentLayout(); // change the size of the content because of adding a title - } - } - - - /** - * @deprecated - * adds a button view to the layout. - *

- * It is called by {@link com.lge.qcircle.template.QCircleTemplate#setBackButton()} to adjust the circle layout. The - * button view is added on the bottom of the layout and the content window will be on the top of - * the button view. - * - * @param buttonView button view to be added.
- * If it is null, the circle layout will not change. - */ - private void addBackButtonView(QCircleBackButton buttonView) { - if (mCircleLayout != null) { - int buttonAreaHeight = (int) (mFullSize * fixedButtonRatio); - // add a button into the bottom of the circle layout - RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(mFullSize, - buttonAreaHeight); - params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 1); - mCircleLayout.addView(buttonView.getView(), params); - adjustContentLayout(); // change the size of the content because of adding a button - } - } - - /** - * @deprecated - * adjust the circle layout when a title view or a button view is added. - *

- * It is called by {@link #addBackButtonView(QCircleBackButton)). - * It changes the relative position of the content window. - */ - protected void adjustContentLayout() { - // get current size of the content - RelativeLayout.LayoutParams contentParams = new RelativeLayout.LayoutParams( - mContent.getLayoutParams().width, mContent.getLayoutParams().height); - // set relative layout parameters - if (mBackButton != null) { - contentParams.addRule(RelativeLayout.ABOVE, mBackButton.getId()); - } - if (mTitle != null) { - contentParams.addRule(RelativeLayout.BELOW, mTitle.getId()); - } - // update layout parameters - mContent.setLayoutParams(contentParams); - } - - /** - * locates the circle on the correct position. The correct position depends on phone model. - *

- */ - protected void setCircleLayout() { - - // 1. get circle size and Y offset - // circle size - initCircleLayoutParam(); + private void changeTitleViewHeight(float heightRatio) { + if (mTitle != null) { + if (heightRatio <= 0) // adjust the height + heightRatio = fixedTitleRatio; + int titleAreaHeight = (int) (mFullSize * heightRatio); + // add a title into the top of the circle layout + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( + LayoutParams.MATCH_PARENT, titleAreaHeight); + params.addRule(RelativeLayout.ALIGN_PARENT_TOP, 1); + mTitle.getView().setLayoutParams(params); + adjustContentLayout(); + } + } + + /** + * @param titleView title view to be added.
+ * If it is null, the circle layout will not change. + * @param heightRatio ratio of the title bar.
+ * If it is less or equal to 0, the height ratio of the title bar will be 0.2 of + * QuickCircle diameter. + * @deprecated adds a title view to the layout. + *

+ * It is called by {@link #setTitle(String)} to adjust the circle layout. The title view is + * added on the top of the layout and the content window will be on the below of the title view. + */ + private void addTitleView(QCircleTitle titleView, float heightRatio) { + if (mCircleLayout != null) { + if (heightRatio <= 0) // adjust the height + heightRatio = fixedTitleRatio; + int titleAreaHeight = (int) (mFullSize * heightRatio); + // add a title into the top of the circle layout + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( + LayoutParams.MATCH_PARENT, titleAreaHeight); + params.addRule(RelativeLayout.ALIGN_PARENT_TOP, 1); + mCircleLayout.addView(titleView.getView(), 0, params); + adjustContentLayout(); // change the size of the content because of adding a title + } + } + + /** + * @param buttonView button view to be added.
+ * If it is null, the circle layout will not change. + * @deprecated adds a button view to the layout. + *

+ * It is called by {@link com.lge.qcircle.template.QCircleTemplate#setBackButton()} to adjust the circle layout. The + * button view is added on the bottom of the layout and the content window will be on the top of + * the button view. + */ + private void addBackButtonView(QCircleBackButton buttonView) { + if (mCircleLayout != null) { + int buttonAreaHeight = (int) (mFullSize * fixedButtonRatio); + // add a button into the bottom of the circle layout + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(mFullSize, + buttonAreaHeight); + params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 1); + mCircleLayout.addView(buttonView.getView(), params); + adjustContentLayout(); // change the size of the content because of adding a button + } + } - // 2. adjust the circle layout for the model - FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(mFullSize, mFullSize); - // circle image - View circleView = (View) mRootLayout.findViewById(R.id.circle); - String device = android.os.Build.DEVICE; - if (circleView != null) { - if (device.equalsIgnoreCase(DEVICE_G3) || device.equalsIgnoreCase(DEVICE_T6)) { - params.topMargin = 0; - } else { - params.topMargin = mTopOffset; - } - params.gravity = Gravity.CENTER_HORIZONTAL; - circleView.setLayoutParams(params); - - } else { - Log.w(TAG, "Cannot found circle image"); - } - // over-circle layout - circleView = (View) mRootLayout.findViewById(R.id.circlelayout); - if (circleView != null) { - circleView.setLayoutParams(params); - } else { - Log.w(TAG, "Cannot found circle layout"); - } - } + /** + * @deprecated adjust the circle layout when a title view or a button view is added. + *

+ * It is called by {@link #addBackButtonView(QCircleBackButton)). + * It changes the relative position of the content window. + */ + protected void adjustContentLayout() { + // get current size of the content + RelativeLayout.LayoutParams contentParams = new RelativeLayout.LayoutParams( + mContent.getLayoutParams().width, mContent.getLayoutParams().height); + // set relative layout parameters + if (mBackButton != null) { + contentParams.addRule(RelativeLayout.ABOVE, mBackButton.getId()); + } + if (mTitle != null) { + contentParams.addRule(RelativeLayout.BELOW, mTitle.getId()); + } + // update layout parameters + mContent.setLayoutParams(contentParams); + } + + /** + * locates the circle on the correct position. The correct position depends on phone model. + *

+ */ + protected void setCircleLayout() { + // 1. get circle size and Y offset + // circle size + initCircleLayoutParam(); + // 2. adjust the circle layout for the model + FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(mFullSize, mFullSize); + // circle image + View circleView = (View) mRootLayout.findViewById(R.id.circle); + String device = android.os.Build.DEVICE; + if (circleView != null) { + if (device.equalsIgnoreCase(DEVICE_G3) || device.equalsIgnoreCase(DEVICE_T6)) { + params.topMargin = 0; + } else { + params.topMargin = mTopOffset; + } + params.gravity = Gravity.CENTER_HORIZONTAL; + circleView.setLayoutParams(params); + + } else { + Log.w(TAG, "Cannot found circle image"); + } + // over-circle layout + circleView = (View) mRootLayout.findViewById(R.id.circlelayout); + if (circleView != null) { + circleView.setLayoutParams(params); + } else { + Log.w(TAG, "Cannot found circle layout"); + } + } /** * locates the circle on the correct position. The correct position depends on phone model. - *

+ *

+ * * @author sujin.cho */ - private boolean initCircleLayoutParam() - { - if(!QCircleFeature.isQuickCircleAvailable(mContext)){ + private boolean initCircleLayoutParam() { + if (!QCircleFeature.isQuickCircleAvailable(mContext)) { Log.i(TAG, "Quick Circle case is not available"); return false; } - // circle size - int id = mContext.getResources().getIdentifier( - "config_circle_diameter", "dimen", "com.lge.internal"); - mFullSize = mContext.getResources().getDimensionPixelSize(id); + mFullSize = QCircleFeature.getTemplateDiameter(mContext); // y position (in G3, y position = y offset) - id = mContext.getResources().getIdentifier( - "config_circle_window_y_pos", "dimen", "com.lge.internal"); - mYpos = mContext.getResources().getDimensionPixelSize(id); + int mYpos = QCircleFeature.getYPosition(mContext); // adjust Y offset for the model - id = mContext.getResources().getIdentifier( - "config_circle_window_height", "dimen", "com.lge.internal"); - int height = mContext.getResources().getDimensionPixelSize(id); + int height = QCircleFeature.getWindowHeight(mContext); mTopOffset = mYpos + ((height - mFullSize) / 2); - return true; } + /** + * sets the design template. + *

+ * + * @param type design template type to be set + */ + protected void setTemplateType(TemplateType type) { + mLayoutType = type; + if (mContext != null) { + View layoutView = null; + switch (mLayoutType) { + case CIRCLE_EMPTY: + Log.d("test", "class name = " + + mContext.getApplicationContext().getPackageName()); + layoutView = ((Activity) mContext).getLayoutInflater().inflate( + R.layout.qcircle_empty, null); + break; + case CIRCLE_COMPLEX: + layoutView = ((Activity) mContext).getLayoutInflater().inflate( + R.layout.qcircle_complex, null); + break; + case CIRCLE_HORIZONTAL: + layoutView = ((Activity) mContext).getLayoutInflater().inflate( + R.layout.qcircle_horizontal, null); + break; + case CIRCLE_VERTICAL: + layoutView = ((Activity) mContext).getLayoutInflater().inflate( + R.layout.qcircle_vertical, null); + break; + case CIRCLE_SIDEBAR: + layoutView = ((Activity) mContext).getLayoutInflater().inflate( + R.layout.qcircle_sidebar, null); + break; + } + initLayout(layoutView); // update root layout with a new template + if (mShouldSetLayoutParams) + setCircleLayout(); // set the circle layout + } else { + Log.w(TAG, "Cannot set the layout. Context is null"); + } + } - /** - * sets the design template. - *

- * - * @param type design template type to be set - */ - protected void setTemplateType(TemplateType type) { - mLayoutType = type; - if (mContext != null) { - View layoutView = null; - switch (mLayoutType) { - case CIRCLE_EMPTY: - Log.d("test", "class name = " - + mContext.getApplicationContext().getPackageName()); - layoutView = ((Activity) mContext).getLayoutInflater().inflate( - R.layout.qcircle_empty, null); - break; - case CIRCLE_COMPLEX: - layoutView = ((Activity) mContext).getLayoutInflater().inflate( - R.layout.qcircle_complex, null); - break; - case CIRCLE_HORIZONTAL: - layoutView = ((Activity) mContext).getLayoutInflater().inflate( - R.layout.qcircle_horizontal, null); - break; - case CIRCLE_VERTICAL: - layoutView = ((Activity) mContext).getLayoutInflater().inflate( - R.layout.qcircle_vertical, null); - break; - case CIRCLE_SIDEBAR: - layoutView = ((Activity) mContext).getLayoutInflater().inflate( - R.layout.qcircle_sidebar, null); - break; - } - initLayout(layoutView); // update root layout with a new template - setCircleLayout(); // set the circle layout - } else { - Log.w(TAG, "Cannot set the layout. Context is null"); - } - - } - - /** - * registers cover event broadcasts. - *

- * The a cover-closed event will make the circle shown and a cover-opened event will make the - * circle hidden after you invoke this method. The full screen intent will starts if you set a - * fullscreen intent by calling {@link #setFullscreenIntent(android.content.Intent)}. - */ - public void registerIntentReceiver() { - if( mContext != null ) { + /** + * registers cover event broadcasts. + *

+ * The a cover-closed event will make the circle shown and a cover-opened event will make the + * circle hidden after you invoke this method. The full screen intent will starts if you set a + * fullscreen intent by calling {@link #setFullscreenIntent(android.content.Intent)}. + */ + public void registerIntentReceiver() { + if (mContext != null) { mReceiver = new BroadcastReceiver() { @Override @@ -741,12 +724,10 @@ public void onReceive(Context context, Intent intent) { if (action == null) { return; } - - if(!QCircleFeature.isQuickCircleAvailable(mContext)){ + if (!QCircleFeature.isQuickCircleAvailable(mContext)) { Log.i(TAG, "Quick Circle case is not available"); return; } - // Receives a LG QCirle intent for the cover event if (ACTION_ACCESSORY_COVER_EVENT.equals(action)) { // Gets the current state of the cover @@ -758,14 +739,18 @@ public void onReceive(Context context, Intent intent) { if (mFullscreenIntent != null && mContext != null) { mContext.startActivity(mFullscreenIntent); } else if (mContent != null && mAsyncCreator != null) { - Intent launching = mAsyncCreator.getIntent(); - if (launching != null) { - try { - mContext.startActivity(launching); - } catch (ActivityNotFoundException e) { - // Package does not exist, ignore. - e.printStackTrace(); + try { + Intent launching = mAsyncCreator.call(); + if (launching != null) { + try { + mContext.startActivity(launching); + } catch (ActivityNotFoundException e) { + // Package does not exist, ignore. + e.printStackTrace(); + } } + } catch (Exception e) { + e.printStackTrace(); } } if (mContext instanceof Activity) { @@ -780,131 +765,134 @@ public void onReceive(Context context, Intent intent) { // Register a broadcast receiver with the system mContext.registerReceiver(mReceiver, filter); } - } + } /** * un-registers a default broadcast receiver.

* It must be called when {@link #registerIntentReceiver) has been called. + * * @author Yoav Sternberg */ - public void unregisterReceiver() { - try { - mContext.unregisterReceiver(mReceiver); - } catch (Exception ignored) { - // Receiver not registered - } - } - - /** - * makes the circle shown even if the screen is locked. - */ - private void setQuickCircleWindowParam() { - if (mContext != null && mContext instanceof Activity) { + public void unregisterReceiver() { + try { + mContext.unregisterReceiver(mReceiver); + } catch (Exception ignored) { + // Receiver not registered + } + } + /** + * makes the circle shown even if the screen is locked. + */ + private void setQuickCircleWindowParam() { + if (mContext != null && mContext instanceof Activity) { //only for Activity extends Activity. does not work for ActionBarActivity.... - ((Activity) mContext).requestWindowFeature(Window.FEATURE_NO_TITLE); - Window win = ((Activity) mContext).getWindow(); - if (win != null) { - // Show the sample application view on top - win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED - | WindowManager.LayoutParams.FLAG_FULLSCREEN - | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON + if (!((Activity) mContext).getWindow().hasFeature(Window.FEATURE_NO_TITLE)) + ((Activity) mContext).requestWindowFeature(Window.FEATURE_NO_TITLE); + Window win = ((Activity) mContext).getWindow(); + if (win != null) { + // Show the sample application view on top + win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED + | WindowManager.LayoutParams.FLAG_FULLSCREEN + | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON ); - } - } - } - - /** - * @deprecated - */ - protected boolean setLayoutById(int id, View view) { - boolean result = false; - if (mContent != null) { - View targetView = getLayoutById(id); - if (targetView != null) { - result = true; - LayoutParams params = targetView.getLayoutParams(); - view.setId(targetView.getId()); - ViewParent parent = targetView.getParent(); - if (parent instanceof LinearLayout) { - LinearLayout layout = (LinearLayout) parent; - layout.removeView(targetView); - layout.addView(view, params); - } else { // maybe RelativeLayout - RelativeLayout layout = (RelativeLayout) parent; - layout.removeView(targetView); - layout.addView(view, params); - } - } - } - return result; - } - - /** - * loads external layout created by users (or user). - *

- * - * @param templateId ID of layout.
- * It should be larger than 0. - */ - protected void loadCustomTemplate(int templateId) { - if (mContext != null && templateId > 0) { - View layoutView = ((Activity) mContext).getLayoutInflater().inflate(templateId, - null); - if (layoutView == null) - Log.w(TAG, "Cannot set the custom layout: " + templateId); - else { - initLayout(layoutView); - setCircleLayout(); - } - } else { - Log.w(TAG, "Cannot set the custom layout. Context is null"); - } - } + } + } + } + + /** + * @deprecated + */ + protected boolean setLayoutById(int id, View view) { + boolean result = false; + if (mContent != null) { + View targetView = getLayoutById(id); + if (targetView != null) { + result = true; + LayoutParams params = targetView.getLayoutParams(); + view.setId(targetView.getId()); + ViewParent parent = targetView.getParent(); + if (parent instanceof LinearLayout) { + LinearLayout layout = (LinearLayout) parent; + layout.removeView(targetView); + layout.addView(view, params); + } else { // maybe RelativeLayout + RelativeLayout layout = (RelativeLayout) parent; + layout.removeView(targetView); + layout.addView(view, params); + } + } + } + return result; + } + + /** + * loads external layout created by users (or user). + *

+ * + * @param templateId ID of layout.
+ * It should be larger than 0. + */ + protected void loadCustomTemplate(int templateId) { + if (mContext != null && templateId > 0) { + View layoutView = ((Activity) mContext).getLayoutInflater().inflate(templateId, + null); + if (layoutView == null) + Log.w(TAG, "Cannot set the custom layout: " + templateId); + else { + initLayout(layoutView); + setCircleLayout(); + } + } else { + Log.w(TAG, "Cannot set the custom layout. Context is null"); + } + } /** * @author Yoav Sternberg + * @deprecated Use Callable instead */ - public static interface IntentCreatorAsync { - Intent getIntent(); - } + @Deprecated + public interface IntentCreatorAsync { + Intent getIntent(); + } /** * Adds a UI element to a template. * * @param element UI element. * The element should extend QCricleTemplateElement abstract class. - * * @author sujin.cho */ - public void addElement(QCircleTemplateElement element) - { + public void addElement(QCircleTemplateElement element) { element.addTo(mCircleLayout, mContent); //remove it later.... - if(element instanceof QCircleBackButton) mBackButton = (QCircleBackButton)element; - else if(element instanceof QCircleTitle) mTitle = (QCircleTitle)element; + if (element instanceof QCircleBackButton) mBackButton = (QCircleBackButton) element; + else if (element instanceof QCircleTitle) mTitle = (QCircleTitle) element; } /** * Returns a diameter of the Quick Circle. This can be used to fit a layout in the Quick Circle window. + * * @return diameter if the "config_circle_diameter" has a value. * -1 if the "config_circle_diameter" is not loaded. */ public int getDiameter() { - if(mFullSize == 0) { - if(initCircleLayoutParam() != true) return -1; + if (mFullSize == 0) { + if (!initCircleLayoutParam()) return -1; } return mFullSize; } /** * Returns a vertical position of the Quick Circle from the top. This can be used to properly locate a layout in the Quick Circle window. + * * @return a position from the top if required configs have values. * -1 if required configs are not loaded. */ public int getYpos() { - if(mTopOffset == 0) { - if(initCircleLayoutParam() != true) return -1; + if (mTopOffset == 0) { + if (!initCircleLayoutParam()) return -1; } return mTopOffset; } diff --git a/designTemplate/src/main/java/com/lge/qcircle/template/QCircleTitle.java b/designTemplate/src/main/java/com/lge/qcircle/template/QCircleTitle.java index 442bfc3..bb4d404 100644 --- a/designTemplate/src/main/java/com/lge/qcircle/template/QCircleTitle.java +++ b/designTemplate/src/main/java/com/lge/qcircle/template/QCircleTitle.java @@ -17,23 +17,23 @@ * * @author jeongeun.jeon */ -public final class QCircleTitle extends QCircleTemplateElement{ +public final class QCircleTitle extends QCircleTemplateElement { - private final String TAG = "QCircleTitle"; + private final String TAG = "QCircleTitle"; private LinearLayout mRootView = null; private TextView mTitleView = null; - //sujin.cho - private RelativeLayout.LayoutParams mParams = null; - private final float fixedTitleRatio = 0.23f; // Title height ratio - private static int mFullSize = 0; // circle diameter + //sujin.cho + private RelativeLayout.LayoutParams mParams = null; + private final float fixedTitleRatio = 0.23f; // Title height ratio + private static int mFullSize = 0; // circle diameter - private boolean useDefaultHeight = true; + private boolean useDefaultHeight = true; /** * creates a title bar with a text. - *

+ *

* It makes a {@link android.widget.TextView} with the given text. * * @param title title text for the title.
@@ -42,16 +42,13 @@ public final class QCircleTitle extends QCircleTemplateElement{ * @param context {@code Activity} which has a circle view.
* If it is null, you might get errors when you use method of this class. */ - public QCircleTitle(Context context, String title) { + public QCircleTitle(Context context, CharSequence title) { this(context, title, Color.BLACK, Color.TRANSPARENT); } - - - - /** + /** * creates a title bar with a text. - *

+ *

* It makes a {@link android.widget.TextView} with the given text. * * @param title title text for the title.
@@ -62,10 +59,29 @@ public QCircleTitle(Context context, String title) { * @param titleTextColor The color of the title * @param backgroundColor The background color of the title */ - public QCircleTitle(Context context, String title, int titleTextColor, int backgroundColor) { + public QCircleTitle(Context context, CharSequence title, int titleTextColor, int backgroundColor) { this(context, createTextView(context, title, titleTextColor), backgroundColor); } + /** + * creates a title bar with a text. + *

+ * It makes a {@link android.widget.TextView} with the given text. + * + * @param title title text for the title.
+ * If it is null, no title text will be shown but the title bar will occupy some + * space. + * @param context {@code Activity} which has a circle view.
+ * If it is null, you might get errors when you use method of this class. + * @param titleTextColor The color of the title + * @param backgroundColor The background color of the title + * @param textSize The text size + */ + public QCircleTitle(Context context, CharSequence title, int titleTextColor, int backgroundColor, float textSize) { + this(context, title, titleTextColor, backgroundColor); + setTextSize(textSize); + } + /** * creates a title bar with the given View. * @@ -90,7 +106,7 @@ public QCircleTitle(Context context, View title) { public QCircleTitle(Context context, View title, int backgroundColor) { if (context != null) { mContext = context; - getTemplateDiameter(context); + mFullSize = QCircleFeature.getTemplateDiameter(context); mRootView = createRootView(context, backgroundColor); if (title != null) { if (title instanceof TextView) mTitleView = (TextView) title; @@ -143,7 +159,7 @@ public boolean setView(View view) { * If it is null, no title text will be shown but the title bar will occupy some * space. */ - public void setText(String title) { + public void setText(CharSequence title) { if (mRootView != null && mTitleView != null) mTitleView.setText(title); else if (mRootView != null) { @@ -164,31 +180,31 @@ public void setTextSize(float size) { } } - /** - * Changes a background color of title view. - * @param color The background color. If 0, no background. Currently must be black, with any desired alpha level. - * @author sujin.cho - */ - public void setBackgroundColor(int color) - { - if(mRootView != null) - mRootView.setBackgroundColor(color); - } + /** + * Changes a background color of title view. + * + * @param color The background color. If 0, no background. Currently must be black, with any desired alpha level. + * @author sujin.cho + */ + public void setBackgroundColor(int color) { + if (mRootView != null) + mRootView.setBackgroundColor(color); + } - /** - * Changes a text color - * @param color The font color. If 0, no background. Currently must be black, with any desired alpha level. - * @author sujin.cho - */ - public void setTextColor(int color) - { - if(mTitleView != null) - mTitleView.setTextColor(color); - } + /** + * Changes a text color + * + * @param color The font color. If 0, no background. Currently must be black, with any desired alpha level. + * @author sujin.cho + */ + public void setTextColor(int color) { + if (mTitleView != null) + mTitleView.setTextColor(color); + } /** * Creates a root layout with a transparent background. - *

+ *

* The root layout will include all of contents for a title bar. * * @param context Activity which has this title bar @@ -200,7 +216,7 @@ private LinearLayout createRootView(Context context) { /** * Creates a root layout. - *

+ *

* The root layout will include all of contents for a title bar. * * @param context Activity which has this title bar @@ -226,7 +242,7 @@ private LinearLayout createRootView(Context context, int backgroundColor) { * @param title title text * @return TextView with the given text */ - private static TextView createTextView(Context context, String title) { + private static TextView createTextView(Context context, CharSequence title) { return createTextView(context, title, Color.BLACK); } @@ -238,7 +254,7 @@ private static TextView createTextView(Context context, String title) { * @param textColor the color of the text * @return TextView with the given text */ - private static TextView createTextView(Context context, String title, int textColor) { + private static TextView createTextView(Context context, CharSequence title, int textColor) { TextView text = new TextView(context); text.setText(title); text.setBackgroundColor(Color.TRANSPARENT); @@ -248,81 +264,50 @@ private static TextView createTextView(Context context, String title, int textCo return text; } - /** - * Adds a title view to parent - *

- * This method is called in QCircleTemplate. First, the methods sets layout parameters for the title. - * Next, the method adds the title to parent. Once the title is added, UIs in the parent needs to be adjusted for the new component. - * - * @param parent QCircle Layout which - * - * @author sujin.cho - */ - @Override - protected void addTo(RelativeLayout parent, RelativeLayout content) { - - if((mRootView != null) && (parent != null)) { - - if(useDefaultHeight == true) { - setLayoutParams(fixedTitleRatio); - } - parent.addView(mRootView); - adjustLayout(content); - } - } - - private void adjustLayout(RelativeLayout content) - { - if(content != null) { - RelativeLayout.LayoutParams contentParams = new RelativeLayout.LayoutParams( - content.getLayoutParams().width, content.getLayoutParams().height); - contentParams.addRule(RelativeLayout.BELOW, mRootView.getId()); - content.setLayoutParams(contentParams); - } - } - - - private void setLayoutParams(float heightRatio) - { - int titleAreaHeight = (int)(mFullSize * heightRatio); - mParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, titleAreaHeight); - mParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, 1); - mRootView.setLayoutParams(mParams); - } - - - /** - * Changes a height of title view. - * @param heightRatio ratio of the portion of title area respect to the circle diameter. - * @author sujin..cho - */ - public void setTitleHeight(float heightRatio) - { - useDefaultHeight = false; - setLayoutParams(heightRatio); - } + /** + * Adds a title view to parent + *

+ * This method is called in QCircleTemplate. First, the methods sets layout parameters for the title. + * Next, the method adds the title to parent. Once the title is added, UIs in the parent needs to be adjusted for the new component. + * + * @param parent QCircle Layout which + * @author sujin.cho + */ + @Override + protected void addTo(RelativeLayout parent, RelativeLayout content) { + if ((mRootView != null) && (parent != null)) { + if (useDefaultHeight) { + setLayoutParams(fixedTitleRatio); + } + parent.addView(mRootView); + adjustLayout(content); + } + } + private void adjustLayout(RelativeLayout content) { + if (content != null) { + RelativeLayout.LayoutParams contentParams = new RelativeLayout.LayoutParams( + content.getLayoutParams().width, content.getLayoutParams().height); + contentParams.addRule(RelativeLayout.BELOW, mRootView.getId()); + content.setLayoutParams(contentParams); + } + } - /** - * Locates the circle on the correct position. The correct position depends on phone model. - *

- * @author sujin.cho - */ - private void getTemplateDiameter(Context context) - { - if(context != null) { - if (!QCircleFeature.isQuickCircleAvailable(context)) { - Log.i(TAG, "Quick Circle case is not available"); - return; - } - // circle size - int id = context.getResources().getIdentifier( - "config_circle_diameter", "dimen", "com.lge.internal"); - mFullSize = context.getResources().getDimensionPixelSize(id); - } - else - { + private void setLayoutParams(float heightRatio) { + int titleAreaHeight = (int) (mFullSize * heightRatio); + mParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, titleAreaHeight); + mParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, 1); + mRootView.setLayoutParams(mParams); + } - } - } + /** + * Changes a height of title view. + * + * @param heightRatio ratio of the portion of title area respect to the circle diameter. + * @author sujin..cho + */ + public void setTitleHeight(float heightRatio) { + useDefaultHeight = false; + setLayoutParams(heightRatio); + } } diff --git a/designTemplate/src/main/java/com/lge/qcircle/utils/QCircleFeature.java b/designTemplate/src/main/java/com/lge/qcircle/utils/QCircleFeature.java index d7d9218..4b25ef8 100644 --- a/designTemplate/src/main/java/com/lge/qcircle/utils/QCircleFeature.java +++ b/designTemplate/src/main/java/com/lge/qcircle/utils/QCircleFeature.java @@ -1,13 +1,12 @@ package com.lge.qcircle.utils; - +import android.app.Activity; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.os.Bundle; import android.provider.Settings; import android.util.Log; -import android.app.Activity; - /** * The {@code QCircleFeature} class provides useful methods for Quick Circle applications. @@ -15,132 +14,196 @@ */ public class QCircleFeature { + //needs to remove intent + private static final String ACTION_UPDATE_NOTIFICATION = "com.lge.launcher.intent.action.BADGE_COUNT_UPDATE"; + private static final int G3_DIAMETER = 1046; + private static int mFullSize = 0; // circle diameter + private final static String TAG = "QCircleFeature"; + /** + * It is possible to run Quick Circle app even if no 'com.lge.internal' package. + * It can be also used for testing (testing LG G3 Beat circle size on LG G3). + */ + private static Bundle mAlternativeValues; + private static boolean mForceAlternativeValues = false; + + /** + * Activates a number badge with a count. + * The number badge will show up on the icon. + * + * @param activity current activity + * @param count a number present in the number badge. The number indicates the number of events occurred. + */ + public static Intent activateNumberBadge(Activity activity, int count) { + Intent numberBadge = new Intent(ACTION_UPDATE_NOTIFICATION); + numberBadge.putExtra("badge_count_package_name", activity.getPackageName()); + numberBadge.putExtra("badge_count_class_name", activity.getClass().getName()); + numberBadge.putExtra("badge_count", count); + return numberBadge; + } + + /** + * Changes a count number of a number badge. + * + * @param activity current activity. + * @param intentForBadge intent created for the number badge. if intentForBadge is null, create a new intent for the number badge. + * @param count a new number for the number badge. + */ + public static void setNumberBadge(Activity activity, Intent intentForBadge, int count) { + if (intentForBadge == null) { + intentForBadge = activateNumberBadge(activity, count); + } + intentForBadge.putExtra("badge_count", count); + } + + /** + * Removes a number badge. + * + * @param activity current activity + * @param intentForBadge intent created for number badge. + */ + public static void removeNumberBadge(Activity activity, Intent intentForBadge) { + if (intentForBadge == null) { + Log.e(TAG, "Intent is null!!"); + } + intentForBadge.putExtra("badge_count", 0); + } + + /** + * Takes a pixel value implemented for the current model. + * The argument value has to be a pixel values. + * Returns a relative pixel value to support other Quick Circle models which have different densities and screen sizes. + * + * @param value a pixel value appropriate for the current device. + * @return + */ + public static int getRelativePixelValue(Context context, int value) { + mFullSize = getTemplateDiameter(context); + return (int) (((double) mFullSize / G3_DIAMETER) * (double) (value)); + } + + /** + * Checks the availability of Quick Circle case. + *

+ * Checks whether a smart case is available and if it is, check the case type. + * + * @param context current application context + */ + public static boolean isQuickCircleAvailable(Context context) { + boolean smartcaseEnabled = false; + int smartcaseType = 0; + if (context != null) { + ContentResolver contentResolver = context.getContentResolver(); + if (contentResolver == null) { + Log.e(TAG, "Content Resolver is null"); + return false; + } + //default is 1. (LG framework setting. When user gets a phone, the case is enable as default) + smartcaseEnabled = Settings.Global.getInt(contentResolver, "quick_view_enable", 1) == 1 ? true : false; + if (!smartcaseEnabled) { + Log.i(TAG, "No smart case available"); + return false; + } + smartcaseType = Settings.Global.getInt(contentResolver, "cover_type", 0); + if (smartcaseType != 3) { + Log.i(TAG, "Case type is not Quick Circle"); + return false; + } + return true; + } else { + Log.e(TAG, "Context is null!!"); + return false; + } + } + + /** + * locates the circle on the correct position. The correct position depends on phone model. + *

+ * + * @author sujin.cho + */ + public static int getTemplateDiameter(Context context) { + if (context != null) { + final String name = "config_circle_diameter"; + if (mForceAlternativeValues) { + return getAlternativeValue(name); + } + int id = context.getResources().getIdentifier( + name, "dimen", "com.lge.internal"); + if (id == 0) { + return getAlternativeValue(name); + } else return context.getResources().getDimensionPixelSize(id); + } + return -1; + } + + /** + * locates the Y position for the template. The correct position depends on phone model. + *

+ */ + public static int getYPosition(Context context) { + if (context != null) { + final String name = "config_circle_window_y_pos"; + if (mForceAlternativeValues) { + return getAlternativeValue(name); + } + int id = context.getResources().getIdentifier( + name, "dimen", "com.lge.internal"); + if (id == 0) { + return getAlternativeValue(name); + } else return context.getResources().getDimensionPixelSize(id); + } + return -1; + } + + /** + * Return the height of the window. The correct position depends on phone model. + *

+ */ + public static int getWindowHeight(Context context) { + if (context != null) { + final String name = "config_circle_window_height"; + if (mForceAlternativeValues) { + return getAlternativeValue(name); + } + int id = context.getResources().getIdentifier( + name, "dimen", "com.lge.internal"); + if (id == 0) { + return getAlternativeValue(name); + } else return context.getResources().getDimensionPixelSize(id); + } + return -1; + } + + public static int getAlternativeValue(String name) { + if (mAlternativeValues == null) return -1; + else return mAlternativeValues.getInt(name, -1); + } + + /** + * Force alternative values + */ + public static void forceAlternativeValues() { + mForceAlternativeValues = true; + } + + /** + * Stop forcing alternative values + */ + public static void StopForceAlternativeValues() { + mForceAlternativeValues = false; + } + + /** + * Set the alternative values.
+ * Possible values:
+ * 1. config_circle_diameter as Int. see {@link #getTemplateDiameter}
+ * 2. config_circle_window_y_pos as Int. see {@link #getYPosition}
+ * 3. config_circle_window_height as Int. see {@link #getWindowHeight}
+ * + * @param alternativeValues Alternative values + */ + public static void setAlternativeValues(Bundle alternativeValues) { + mAlternativeValues = alternativeValues; + } - //needs to remove intent - private static final String ACTION_UPDATE_NOTIFICATION = "com.lge.launcher.intent.action.BADGE_COUNT_UPDATE"; - private static final int G3_DIAMETER = 1046; - private static int mFullSize = 0; // circle diameter - private final static String TAG = "QCircleFeature"; - - /** - * Activates a number badge with a count. - * The number badge will show up on the icon. - * @param activity current activity - * @param count a number present in the number badge. The number indicates the number of events occurred. - */ - public static Intent activateNumberBadge(Activity activity, int count) - { - Intent numberBadge = new Intent(ACTION_UPDATE_NOTIFICATION); - numberBadge.putExtra("badge_count_package_name", activity.getPackageName()); - numberBadge.putExtra("badge_count_class_name", activity.getClass().getName()); - numberBadge.putExtra("badge_count", count); - return numberBadge; - } - - /** - * Changes a count number of a number badge. - * @param activity current activity. - * @param intentForBadge intent created for the number badge. if intentForBadge is null, create a new intent for the number badge. - * @param count a new number for the number badge. - */ - public static void setNumberBadge(Activity activity, Intent intentForBadge, int count) - { - if(intentForBadge == null) - { - intentForBadge = activateNumberBadge(activity,count); - } - intentForBadge.putExtra("badge_count", count); - } - - /** - * Removes a number badge. - * @param activity current activity - * @param intentForBadge intent created for number badge. - */ - public static void removeNumberBadge(Activity activity, Intent intentForBadge) - { - if(intentForBadge == null) - { - Log.e(TAG, "Intent is null!!"); - } - intentForBadge.putExtra("badge_count", 0); - } - - /** - * Takes a pixel value implemented for the current model. - * The argument value has to be a pixel values. - * Returns a relative pixel value to support other Quick Circle models which have different densities and screen sizes. - * @param value a pixel value appropriate for the current device. - * @return - */ - public static int getRelativePixelValue(Context context, int value) - { - getTemplateDiameter(context); - return (int)(((double) mFullSize/G3_DIAMETER) * (double)(value)); - } - - - /** - * Checks the availability of Quick Circle case. - *

- * Checks whether a smart case is available and if it is, check the case type. - * @param context current application context - */ - public static boolean isQuickCircleAvailable(Context context) - { - - boolean smartcaseEnabled = false; - int smartcaseType = 0; - - if(context != null){ - ContentResolver contentResolver = context.getContentResolver(); - - if(contentResolver == null) - { - Log.e(TAG, "Content Resolver is null"); - return false; - } - //default is 1. (LG framework setting. When user gets a phone, the case is enabled as default) - smartcaseEnabled = Settings.Global.getInt(contentResolver,"quick_view_enable", 1) == 1 ? true : false; - if(!smartcaseEnabled) { - Log.i(TAG, "No smart case available"); - return false; - } - - smartcaseType = Settings.Global.getInt(contentResolver, "cover_type", 0); - if(smartcaseType != 3){ - Log.i(TAG, "Case type is not Quick Circle"); - return false; - } - return true; - } - else{ - - Log.e(TAG, "Context is null!!"); - return false; - } - } - - /** - * locates the circle on the correct position. The correct position depends on phone model. - *

- * @author sujin.cho - */ - private static void getTemplateDiameter(Context context) - { - if(context != null) { - if (!QCircleFeature.isQuickCircleAvailable(context)) { - Log.i(TAG, "Quick Circle case is not available"); - return; - } - // circle size - int id = context.getResources().getIdentifier( - "config_circle_diameter", "dimen", "com.lge.internal"); - mFullSize = context.getResources().getDimensionPixelSize(id); - } - else - { - - } - } } diff --git a/designTemplate/src/main/res/drawable/circlebackground.png b/designTemplate/src/main/res/drawable-nodpi/circlebackground.png similarity index 100% rename from designTemplate/src/main/res/drawable/circlebackground.png rename to designTemplate/src/main/res/drawable-nodpi/circlebackground.png