Sample Code Analysis

 

This page analyzes each code of the sample applications to show how to develop QSlide applications.

 

For detailed description of each API, please refer to API reference.

 

API Sample

The API sample consists of the following files:

 

Files

Description

src/com/lge/qslideapi/sample/QSlideFloatableActivity.java

Main activity class

res/layout/activity_qslide_fullscreen.xml

Layout file for the main activity in full screen

res/layout/activity_qslide_floating_window.xml

Layout file for the floating window

res/values/styles.xml

Style file for the activity

In this section, only java source files and the style file are described. Detailed descriptions of the layout files can be found in Android Developer site.

 

Getting Ready

All codes described below can be found in QSlideFloatableActivity.java.

 

Importing the QSlide Package

All classes using the LG QSlide APIs must import the LG QSlide package as follows:

import com.lge.app.floating.*;

 

Creating an Activity that extends FloatableActivity

The Activity should inherit from FloatableActivity class to use LG QSlide APIs.

public class QslideFloatingActivity
                           extends FloatableActivity {

 

Setting layout for the floating window

The sample application has different views for full screen and floating window mode. To make it different, two layout files should be created and taken for two modes respectively.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_qslide_fullscreen); ①   
    …
    setContentViewForFloatingMode(
            R.layout.activity_qslide_floating_window); ②
}

① Sets layout for full screen. This code is used for setting layout for normal Activities, too.

② Sets layout for the floating window. 

 

Switching the Mode

The sample application has the button to switch to or from the floating window mode. It is needed to implement an onTouchListener interface for switching mode when users touch the button.

@Override

protected void onCreate(Bundle savedInstanceState) {
    …
    mSwitchButton.setOnTouchListener(mListener);①
    …
}

OnTouchListener mListener = new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        boolean floatingmode = isInFloatingMode();② 

        if (event.getAction() ==
                      MotionEvent.ACTION_DOWN ) {    ③
            // code for change images of the button
          // when it is pressed
            return true;
        } 
        else if (event.getAction() ==
                              MotionEvent.ACTION_UP) {  ④
            // code for change images of the button
          // when it is released
            if(floatingmode) {
                getFloatingWindow().close(true); ⑤
            } else {
                boolean useOverlay = 
                         mUseOverlayCheckbox.isChecked();⑥
                boolean useOverlappingTitle =
              mUseOverlappingTitleCheckbox.isChecked(); ⑥
                boolean isResizable = 
                         mIsResizableCheckbox.isChecked();⑥

                switchToFloatingMode(useOverlay, ⑦
                                         useOverlappingTitle, 
                                         isResizable, null);
            }
            return true;
        }
        return false;
    }
};

In the above code, mSwitchButton.setOnTouchListener() is called in the onCreate() method of QSlideFloatableActivity. And the listener is defined outside of the onCreate() method.

 

① sets onTouchListener of the button. 

② gets the flag that indicates whether the Activity is in the floating window or not.

③ handles the case when users press the button. In that case, the sample application changes the image of the button to show the button is being pressed. In this document, codes for changing the image are omitted.

④ handles the case when users release the button. In that case, the sample application changes the image of the button and switches the mode of the Activity. Switching mode is performed depending on the current mode.

⑤ switches back to the full screen if the Activity is in the floating window. The window will be closed and the full screen Activity will appear.

⑥ gets options from the UI components. Those options are used to set the floating window.

⑦ switches the Activity into the floating window with options applied. The last parameter of the function is the size of the floating window. null means that the window will be created with the initial size or the last used size.

 

If false value is added to the method: getFloatingWindow().close(false), Application will be closed completely. Alternatively use getFloatingWindow().close(). It also closes the Activity.

 

Handling Activity Lifecycle

Compared with Activity, FloatableActivity has two additional callbacks to manage lifecycle: onAttachedToFloatingWindow() and onDetachedFromFloatingWindow().

The sample application implements the callbacks to show how to use these callbacks.

 

For detailed description of lifecycle, please see the Development. 

@Override

public void onAttachedToFloatingWindow(FloatingWindow w){ ①
    Log.v(TAG,"onAttachedToFloatingWindow."); 
    mSwitchButton = (ImageButton)findViewById(
                                     R.id.switch_button);
    mSwitchButton.setOnTouchListener(mListener); ②
    …
}

@Override
public boolean onDetachedFromFloatingWindow( ③
                       FloatingWindow w,
                       boolean isReturningToFullScreen) {
Log.v(TAG,"onDetachedFromFloatingWindow. " +
            "Returning to Fullscreen: " + 
                  isReturningToFullScreen);

    Intent intent = getIntent();
    intent.putExtra("posX", w.getLayoutParams().x); ④
    intent.putExtra("posY", w.getLayoutParams().y); ④

    return true;
}

① Implements onAttachedToFloatingWindow() which is called when the floating window becomes visible to users. 

All resources should be reinitialized in this method if the new layout for the floating window was set by calling setContentViewForFloatingMode(). 

② sets an onTouchListener for the switch button on the floating window.

The instances of switch buttons on the full screen and the floating window are different. Setting an onTouchListener for the button on the floating window is needed because the onTouchListener for button on the full screen is not valid on the floating window. 

③ Implements onDetachedFromFloatingWindow() which is called when the floating window is closed.

④ sets extras to let the Activity show the last position of the floating window.

 

Printing the Last Position of the Floating Window

The last position of the floating window sent through the Intent is shown when the floating window switches back to the full screen.

 

protected void onCreate(Bundle savedInstanceState) {
    …
    if( mInfoText != null ) {
        int mPosX = getIntent().getIntExtra("posX", -1); ①
        int mPosY = getIntent().getIntExtra("posY", -1); ① 

        if( mPosX != -1 && mPosY != -1 )   ②
        {
            mInfoText.setText("The last position of the " +
                                  "floating window:\n"+
                                  "X: " + mPosX +
                                  "\nY: " + mPosY);
        }
}

① gets the last position of the floating window from the Intent.

② prints out the last position of the floating window only if the position value is valid.

 

Implementing an onUpdateListener

In the sample application, the width of floating window is limited. An onUpdateListener notifies the size of the window whenever the size is changed.

@Override

public void onAttachedToFloatingWindow(FloatingWindow w) {
w.setOnUpdateListener(new FloatingWindow
                  .DefaultOnUpdateListener() { ①
        public void onResizeFinished( ②
            FloatingWindow window, int width, int height){
            if( width > 800 ) ③
                window.setSize(800, height);
        }
    });
}

① sets onUpdateListener of the floating window. A new instance of DefaultOnUpdateListener should be created. DefaultOnUpdateListener makes it easy to implement the interface. It enables developers to override the partial callbacks instead of implementing all callbacks defined in the onUpdateListener interface.

② implements the callback which is called when the size of the floating window is changed. The sample application specifies this callback only. Developers can implement other callbacks like onClosing(), onMoveFinished(), etc.

③ checks whether the width of the floating window is equal to or less than 800 pixels. If not, change the width to 800 pixcels.

 

Modifying Theme

In order to avoid the flickering effect during the transition from the full screen mode to the floating mode, the sample application disables the window preview feature and window animation. To do so, add following two items into the theme resource that your activity is referencing. 




① disables the window preview feature.

② disables the window animation. 

Luna Lander

Lunar lander consists of the following files:

 

Files

Description

src/com/example/android/luanrlander/LunarLander.java

Main activity class

src/com/example/android/luanrlander/LunarView.java

Game screen class

res/layout/lunar_layout.xml

Layout file for the game

res/values/styles.xml

Style file for the activity

In this page, codes that are modified to make the game as a QSlide application are described.

 

Changing the Super Class

The main activity should inherit from FloatableActivity class.

public class LunarLander extends FloatableActivity {		

 

Adding Switch Buttons

The original game does not have a switch button. Add a button and enable users to switch the game into the floating window when the button is clicked.

@Override
protected void onCreate(Bundle savedInstanceState) {
    …
    qslideButton = (ImageView) findViewById(
                                R.id.imageView1);     ①
    …
    qslideButton.setOnClickListener(
                     new View.OnClickListener() {  ②
        @Override
        public void onClick(View v) {
            switchToFloatingMode();   ②
        }
    });
    …
}

@Override
public void onAttachedToFloatingWindow(FloatingWindow w) {    
    …
    if (isInFloatingMode()) {        ③
        qslideButton.setVisibility(View.GONE);
    } else {
        qslideButton.setVisibility(View.VISIBLE);
    }
    …
}

① gets the instance of the switch button.

② adds an onClickListener to the button and makes the screen switch to the floating window when the button is clicked.

③ hides the switch button when the game is in the floating window mode, shows the button when the game is in the full window mode. This is implemented in onAttachedToFloatingWindow() callback.

 

Resizing Gaming Elements

Elements on the screen like a lunar lender and the goal spot should be resized when the game screen is switched to the floating window or the floating window is resized.

@Override
public void onAttachedToFloatingWindow(FloatingWindow w) {    
    …
    resizedWidthRatio = (float)
               w.getLayoutParams().width /           ①
               ((WindowManager) getApplicationContext()
                 .getSystemService(Context.WINDOW_SERVICE))
                 .getDefaultDisplay().getWidth();
    mLunarView.setResizeRatio(resizedWidthRatio); ②

    w.setOnUpdateListener(new FloatingWindow
                         .DefaultOnUpdateListener(){ ③
        @Override
        public void onResizeFinished(
                  FloatingWindow window, int width,
                  int height) {③
            resizedWidthRatio = (float) width /  ①
           ((WindowManager)getApplicationContext()
                   .getSystemService(Context.WINDOW_SERVICE))
                   .getDefaultDisplay().getWidth();
            mLunarView.setResizeRatio(resizedWidthRatio); ②
       }
    });
    …
}

① calculates the ratio of the floating window’s width to the full scree’s.

② resizes gaming elements by calling setResizeRatio() of the LunarView class. For detailed codes for the method, please see LunarView.java.

③ adds an onUpdateListener to the floating window. onResizeFinished() callback has to be implemented to resize gaming elements when the size of the window is changed.

 

Navigation