self-defined AppWidget:
If you need define your own appwidget, you need two steps:
first: define your layout. In the res/layout folder define a .xml, in the xml file, describe the widget's face.
second: define your widget code. Because others use your widget from a class. So you must define a .java file. In your java file there must be one class named your widget name class extends layout(Linerlayout, Relativelayout or others) . And In the class define the clicklistener.
Example Code:
The .xml file
<?xml version="1.0" encoding="utf-8"?> 2 <merge xmlns:android="http://schemas.android.com/apk/res/android"> 3 4 <ImageView 5 android:id="@+id/pc_speed_rew" 6 android:layout_width="@dimen/playback_controls_speed_indicator_width" 7 android:layout_height="@dimen/playback_controls_speed_indicator_height" 8 android:src="@drawable/speed_indicator" /> 9 10 <ImageView 11 android:id="@+id/pc_button_rew" 12 android:layout_width="@dimen/playback_controls_rew_ff_button_width" 13 android:layout_height="@dimen/playback_controls_rew_ff_button_height" 14 android:src="@drawable/button_rew" 15 android:focusable="true" 16 android:clickable="true" /> 17 18 <com.jamdeo.tv.ui.widget.ButtonPlay 19 xmlns:tvuicomponents="http://schemas.android.com/apk/res-auto" 20 android:id="@+id/pc_button_play" 21 android:layout_width="@dimen/playback_controls_play_button_width" 22 android:layout_height="@dimen/playback_controls_play_button_height" 23 android:background="@drawable/selector_play" 24 android:focusable="true" 25 android:clickable="true" 26 tvuicomponents:stroke_width="@dimen/playback_controls_progress_indicator_stroke_width" 27 tvuicomponents:stroke_color="@color/playback_controls_progress_indicator_stroke_color" 28 android:padding="@dimen/playback_controls_progress_indicator_padding" /> 29 30 <ImageView 31 android:id="@+id/pc_button_ff" 32 android:layout_width="@dimen/playback_controls_rew_ff_button_width" 33 android:layout_height="@dimen/playback_controls_rew_ff_button_height" 34 android:src="@drawable/button_ff" 35 android:focusable="true" 36 android:clickable="true" /> 37 38 <ImageView 39 android:id="@+id/pc_speed_ff" 40 android:layout_width="@dimen/playback_controls_speed_indicator_width" 41 android:layout_height="@dimen/playback_controls_speed_indicator_height" 42 android:src="@drawable/speed_indicator" /> 43 44 </merge>
The class code:
package
import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import your layout file path import java.security.InvalidParameterException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; /** * <p> * Set of controls for video playback. It consist of * Play/Pause button. * Rewind button * Fast forward button * Speed indicator for forward or rewind speed. * Video progress indicator * * */ public class PlaybackControls extends LinearLayout{ private static final List<Integer> REW_SPEEDS = Collections.unmodifiableList( Arrays.asList(-1, -2, -4, -8, -16, -32)); private static final List<Integer> FF_SPEEDS = Collections.unmodifiableList( Arrays.asList(1, 2, 4, 8, 16, 32)); private ImageView mButtonRew; private ButtonPlay mButtonPlay; private ImageView mButtonFf; private ImageView mSpeedIndicatorRew; private ImageView mSpeedIndicatorFf; private int mSpeed = FF_SPEEDS.get(0); private onClickControlListener mListener; /** * It is used to identify playback control. * */ public enum ControlType { /** * Rewind button. */ REWIND, /** * Play or pause button. */ PLAY_PAUSE, /** * Fast forward button. */ FAST_FORWARD } public interface onClickControlListener { void onClick(PlaybackControls pc, ControlType control); } private class OnClickListenerWrapper implements OnClickListener { private final ControlType mControl; OnClickListenerWrapper(ControlType control) { mControl = control; } @Override public void onClick(View v) { if (mListener != null) { mListener.onClick(PlaybackControls.this, mControl); } } } public PlaybackControls(Context context) { this(context, null); } public PlaybackControls(Context context, AttributeSet attrs) { this(context, attrs, -1); } public PlaybackControls(Context context, AttributeSet attrs, int defStyle) { super(PR.getPackageContextForResources(context), attrs, defStyle); init(context); } private void init(Context context) { setGravity(Gravity.CENTER_VERTICAL); Context resContext = PR.getPackageContextForResources(context); inflate(resContext, PR.layout.playback_controls, this); setFocusable(true); mButtonRew = (ImageView) findViewById(PR.id.pc_button_rew); mButtonPlay = (ButtonPlay) findViewById(PR.id.pc_button_play); mButtonFf = (ImageView) findViewById(PR.id.pc_button_ff); mSpeedIndicatorRew = (ImageView) findViewById(PR.id.pc_speed_rew); mSpeedIndicatorFf = (ImageView) findViewById(PR.id.pc_speed_ff); mButtonRew.setOnClickListener(new OnClickListenerWrapper(ControlType.REWIND)); mButtonPlay.setOnClickListener(new OnClickListenerWrapper(ControlType.PLAY_PAUSE)); mButtonFf.setOnClickListener(new OnClickListenerWrapper(ControlType.FAST_FORWARD)); } /** * Register a callback to be invoked when this control is clicked. * * @param l The callback that will run */ public void setOnClickControlListener (onClickControlListener l) { mListener = l; } /** * Set the current progress for Video progress indicator to the specified value. * * @param progress the new progress, between 0 and getMax() */ public void setProgress(int progress) { mButtonPlay.setProgress(progress); } /** * Get the Video progress indicator's current level of progress. * * @return the current progress, between 0 and getMax() */ public int getProgress() { return mButtonPlay.getProgress(); } /** * Set the range of the Video progress indicator to 0...max.. * * @param max the upper range of Video progress indicator */ public void setProgressMax(int max) { mButtonPlay.setMax(max); } /** * Return the upper limit of Video progress indicator's range. * * @return a positive integer */ public int getProgressMax() { return mButtonPlay.getMax(); } /** * Set value for play state. * BUTTON_PP is used as play button when is it set to true. * BUTTON_PP is used as pause button when is it set to false. * * @param b value for play state */ public void setPlayState(boolean b) { mButtonPlay.setPlayState(b); } /** * Get value for play state. * BUTTON_PP is used as play button when is it set to true. * BUTTON_PP is used as pause button when is it set to false. * * @return value for play state */ public boolean getPlayState(){ return mButtonPlay.getPlayState(); } /** * Set level for Speed indicator. * The speed indicator supports values returned by * getSupportedRewSpeeds() and getSupportedFfSpeeds(). * * @param speed The new speed level. */ public void setSpeed(int speed) { if (!REW_SPEEDS.contains(speed) && !FF_SPEEDS.contains(speed)) { throw new IllegalArgumentException("Speed level " + speed + " is not supported"); } mSpeed = speed; mSpeedIndicatorRew.setImageLevel(mSpeed < 0 ? -mSpeed : 0); mSpeedIndicatorFf.setImageLevel(mSpeed > 0 ? mSpeed : 0); } /** * Get current level for Speed indicator. * * @return current level for Speed indicator. */ public int getSpeed() { return mSpeed; } /** * Get list of supported REW speeds by the Speed indicator. * Negative values is used for REW. * * @return list with supported speeds. */ public List<Integer> getSupportedRewSpeeds() { return REW_SPEEDS; } /** * Get list of supported FF speeds by the Speed indicator. * Positive values is used for FF. * * @return list with supported speeds. */ public List<Integer> getSupportedFfSpeeds() { return FF_SPEEDS; } /** * Set the enabled state of the control. * * @param c The control for which the enable state is being set * @param enabled True if the control is enabled, false otherwise. */ public void setEnabled (ControlType c, boolean enabled) { switch(c) { case REWIND: mButtonRew.setEnabled(enabled); mButtonRew.setFocusable(enabled); break; case PLAY_PAUSE: mButtonPlay.setEnabled(enabled); mButtonPlay.setFocusable(enabled); break; case FAST_FORWARD: mButtonFf.setEnabled(enabled); mButtonFf.setFocusable(enabled); break; } } /** * Disable or enable all controls. * * @param enabled True for enable, false otherwise. */ @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); mButtonRew.setEnabled(enabled); mButtonRew.setFocusable(enabled); mButtonPlay.setEnabled(enabled); mButtonPlay.setFocusable(enabled); mButtonFf.setEnabled(enabled); mButtonFf.setFocusable(enabled); } /** * Returns the enabled status for the control. * * @param c The control for which the enable state is being got * @return True if the control is enabled, false otherwise. */ public boolean isEnabled (ControlType c) { switch(c) { case REWIND: return mButtonRew.isEnabled(); case PLAY_PAUSE: return mButtonPlay.isEnabled(); case FAST_FORWARD: return mButtonFf.isEnabled(); default: throw new InvalidParameterException(); } } /** * Enable the focus status for the control type * * @param c The control to be enable the focus */ public void setFocus(ControlType c) { switch (c) { case REWIND: mButtonRew.requestFocus(); break; case PLAY_PAUSE: mButtonPlay.requestFocus(); break; case FAST_FORWARD: mButtonFf.requestFocus(); break; } } @Override protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); if (gainFocus && isFocused()) { mButtonPlay.requestFocus(); } } @Override public void addFocusables(ArrayList<View> views, int direction, int focusableMode) { if (hasFocus()) { super.addFocusables(views, direction, focusableMode); } else { views.add(this); } } }