Add a sample for handling hover events.

Change-Id: I9e19e09d3f5b8d0fd03f52cc8d88e6a12399d12f
This commit is contained in:
Jeff Brown
2011-06-27 21:37:37 -07:00
parent e89c5e20a0
commit 402adc44c2
8 changed files with 327 additions and 0 deletions

View File

@@ -2038,6 +2038,13 @@
</intent-filter>
</activity>
<activity android:name=".view.Hover" android:label="Views/Hover Events">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" />
</intent-filter>
</activity>
<!-- ************************************* -->
<!-- GRAPHICS SAMPLES -->
<!-- ************************************* -->

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/hover_background_active" android:state_hovered="true" />
<item android:drawable="@drawable/hover_background_inactive" />
</selector>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ffdddd00"/>
<stroke android:width="3dp" color="#ff000000"/>
<corners android:radius="3dp" />
<padding android:left="10dp" android:top="10dp"
android:right="10dp" android:bottom="10dp" />
</shape>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#f0600000"/>
<stroke android:width="3dp" color="#ffff8080"/>
<corners android:radius="3dp" />
<padding android:left="10dp" android:top="10dp"
android:right="10dp" android:bottom="10dp" />
</shape>

View File

@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Hover event handling demo. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hover_description"
android:padding="12dip" />
<TextView
android:id="@+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hover_message_initial"
android:padding="12dip" />
<CheckBox
android:id="@+id/intercept_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hover_intercept_checkbox" />
<com.example.android.apis.view.HoverInterceptorView
android:id="@+id/interceptor"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/intercept_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hover_intercept_message_initial"
android:padding="12dip" />
<!-- This button uses a state-list drawable to select among
different shapes based on its current hover state. -->
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/hover_background"
android:text="@string/hover_button" />
</com.example.android.apis.view.HoverInterceptorView>
</LinearLayout>

View File

@@ -869,6 +869,19 @@
<string name="game_controller_input_key_pressed">Pressed</string>
<string name="game_controller_input_key_released">Released</string>
<string name="hover_description">
This activity demonstrates how to handle hover events with View.onHoverEvent,
ViewGroup.onInterceptHoverEvent, and View.setOnHoverListener.
</string>
<string name="hover_intercept_checkbox">Make container intercept hover events</string>
<string name="hover_message_initial">Try using a mouse or touch pad to hover over views within this activity.</string>
<string name="hover_message_entered_at">Entered the container at (%1$f,%2$f).</string>
<string name="hover_message_moved_at">Moved within the container at (%1$f,%2$f).</string>
<string name="hover_message_exited_at">Exited the container at (%1$f,%2$f). The pointer may be inside the bounds of a child instead.</string>
<string name="hover_intercept_message_initial">Try hovering over the button.</string>
<string name="hover_intercept_message_intercepted">Intercepted hover event instead of sending it to the button. Om nom nom!</string>
<string name="hover_button">Hover Here</string>
<!-- ============================== -->
<!-- GoogleLogin examples strings -->
<!-- ============================== -->

View File

@@ -0,0 +1,106 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.apis.view;
import com.example.android.apis.R;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
/**
* Demonstrates how to use {@link View#onHoverEvent}, {@link ViewGroup#onInterceptHoverEvent},
* and {@link View#setOnHoverListener}.
*
* This activity displays a few buttons and text fields and entices the user
* to hover over them using a mouse or touch pad. It displays feedback reporting
* the position of the pointing device and the label of the view being hovered.
*
* A button changes from dark green to bright yellow when hovered.
* This effect is achieved by using a state-list drawable to select among different
* background shapes and colors based on the hover state of the button.
*
* A {@link View#OnHoverEventListener} is used to listen for hover events within the
* container. The container will re
*
* A checkbox is used to control whether a special view, the Interceptor, will intercept
* events before they are sent to its child (a button). When the Interceptor
* is intercepting events, the button will not change state as the pointer hovers
* over it because the interceptor itself will grab the events.
*/
public class Hover extends Activity {
private TextView mMessageTextView;
private CheckBox mInterceptCheckBox;
private HoverInterceptorView mInterceptor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hover);
mMessageTextView = (TextView) findViewById(R.id.message);
mInterceptCheckBox = (CheckBox) findViewById(R.id.intercept_checkbox);
mInterceptor = (HoverInterceptorView) findViewById(R.id.interceptor);
View container = findViewById(R.id.container);
container.setOnHoverListener(new View.OnHoverListener() {
@Override
public boolean onHover(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_HOVER_ENTER:
mMessageTextView.setText(Hover.this.getResources().getString(
R.string.hover_message_entered_at,
event.getX(), event.getY()));
break;
case MotionEvent.ACTION_HOVER_MOVE:
mMessageTextView.setText(Hover.this.getResources().getString(
R.string.hover_message_moved_at,
event.getX(), event.getY()));
break;
case MotionEvent.ACTION_HOVER_EXIT:
mMessageTextView.setText(Hover.this.getResources().getString(
R.string.hover_message_exited_at,
event.getX(), event.getY()));
break;
}
return false;
}
});
mInterceptCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mInterceptor.setInterceptHover(isChecked);
}
});
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.apis.view;
import com.example.android.apis.R;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* Part of the {@link Hover} demo activity.
*
* The Interceptor view is a simple subclass of LinearLayout whose sole purpose
* is to override {@link #onInterceptHoverEvent}. When the checkbox in the
* hover activity is checked, the interceptor view will intercept hover events.
*
* When this view intercepts hover events, its children will not receive
* hover events. This can be useful in some cases when implementing a custom
* view group that would like to prevent its children from being hovered
* under certain situations. Usually such custom views will be much more
* interesting and complex than our little Interceptor example here.
*/
public class HoverInterceptorView extends LinearLayout {
private boolean mInterceptHover;
public HoverInterceptorView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptHoverEvent(MotionEvent event) {
if (mInterceptHover) {
return true;
}
return super.onInterceptHoverEvent(event);
}
@Override
public boolean onHoverEvent(MotionEvent event) {
TextView textView = (TextView) findViewById(R.id.intercept_message);
if (mInterceptHover && event.getAction() != MotionEvent.ACTION_HOVER_EXIT) {
textView.setText(getResources().getString(
R.string.hover_intercept_message_intercepted));
return true;
}
textView.setText(getResources().getString(
R.string.hover_intercept_message_initial));
return super.onHoverEvent(event);
}
public void setInterceptHover(boolean intercept) {
mInterceptHover = intercept;
}
}