本文原创http://blog.youkuaiyun.com/yanbin1079415046,转载请注明出处。
前段时间项目中增加了这样一个需求:用户第一次进入程序的时候,在程序新增功能的地方以冒泡的方式提示用户此处有新功能。功能比较简单,在此与大家分享一下。效果图如下:
用户第一次进入程序:
用户点击屏幕的任何地方后:
下面就来简单的说一下该功能的实现。
思路:
关于布局,我这里采用的方式是:最外层是自己定义的一个MyRelativeLayout(继承自RelativeLayout,重写dispatchTouchEvent()方法);紧接着RelativeLayout,里面放一个LinearLayout,LinearLayout里三个button;接下来是一个RelativeLayout,它里面放一个ListView,给它设置below属性,在第一个RelativeLayout的下面;最后为一个RelativeLayout,它也在第一个RelativeLayout的下面,里面放一个Button,就是我们的tip。
关于tip消失:用户第一次进入程序的时候,从SharedPreference中读取一个标志位(是否第一次进入该页面)。如果用户是第一次进入该页面,则显示tip。此时有两种操作可选:用户点击了屏幕的任一位置,dispatchTouchEvent()方法中会发送一个广播给主页面,然后主页面就将tip隐藏掉,并且将SharedPreference设置已经进入过程序一次。当用户在五秒内为点击屏幕,而tip在显示五秒后自动消失。
界面也简单,功能也简单,做法也简单。现在就对着代码稍微说一下,有兴趣的朋友可以下载demo看看。
xml布局文件:main.xml,布局之前已经说过。
<?xml version="1.0" encoding="utf-8"?>
<yanbin.showtip.MyRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:background="@android:color/darker_gray"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
tools:context=".ShowTipActivity" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/main_top"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="10dp"
>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginRight="15dp"
android:id="@+id/main_btn1"
android:text="按钮A"
android:onClick="click"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginRight="15dp"
android:id="@+id/main_btn2"
android:text="按钮B"
android:onClick="click"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/main_btn3"
android:text="按钮C"
/>
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/main_bottom"
android:layout_below="@id/main_top"
>
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/listview"
android:cacheColorHint="#00000000"
></ListView>
</RelativeLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/iv_float"
android:visibility="gone"
android:layout_below="@+id/main_top"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="@drawable/tip"
android:gravity="center_horizontal"
android:id="@+id/tip_btn"
android:onClick="click"
android:text="这是一个tip" />
</RelativeLayout>
</yanbin.showtip.MyRelativeLayout>
MyRelativeLayout就是自定义的类,它的作用是:当用户点击屏幕时:发送一个广播给主Activity,该Activity接收到广播后隐藏tip。它的代码如下:
package yanbin.showtip;
import android.content.Context;
import android.content.Intent;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.RelativeLayout;
/**
* 自定义RelativeLayout
* 目的就是在最外面的RelativeLayout捕获到事件
* 并且进行事件分发的时候,给要显示tip的Activity页面发送一个广播,页面在接收到广播
* 之后将tip框隐藏即可。
* @author yanbin
*
*/
public class MyRelativeLayout extends RelativeLayout {
public Context context;
public MyRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
}
public MyRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
public MyRelativeLayout(Context context) {
super(context);
this.context = context;
}
/**
* 重写分发点击事件的方法,由于它是最外层的ViewGroup,会首先被调用,但是我们这里返回值为
* super.dispatchTouchEvent(ev),也就是调用系统默认的处理,返回的true,它会把事件
* 分发给另一个需要的控件来处理
*/
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Intent intent = new Intent();
intent.setAction("yanbin.showtip.receiver");
context.sendBroadcast(intent);
return super.dispatchTouchEvent(ev);
}
}
接下就是我们的主Activity,ShowTipActivity.java。
它分为两个流程:
1、用户五秒内没点击屏幕,tip自动消失。涉及到的方法如下:
//显示tip框,如果用户5秒内没有点击屏幕,则tip自动消失
private void showTip() {
mRec = new MyRelativeLayoutRec();
IntentFilter myFilter = new IntentFilter();
myFilter.addAction("yanbin.showtip.receiver");
registerReceiver(mRec, myFilter);
iv_float.setVisibility(View.VISIBLE);
Editor editor = sp.edit();
editor.putInt("isFirst", 1);
editor.commit();
TimerTask task = new TimerTask() {
@Override
public void run() {
//注意不要在这里在直接去隐藏tip,因为它不在住UI中
//通知主线程更新view
sendMsgToUI(HIDE_TIP);
}
};
Timer timer = new Timer();
timer.schedule(task, 5000);
}
@SuppressLint({ "HandlerLeak", "HandlerLeak" })
private void sendMsgToUI(int what){
Message m = new Message();
m.what = what;
mHandler.sendMessage(m);
}
2、用户五秒内点击屏幕,tip消失。涉及到的方法如下(showTip中的MyRelativeLayoutRec的具体代码):
/**
* 使用广播接收者来处理tip隐藏的事件
* @author yanbin
*/
private class MyRelativeLayoutRec extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//由于不是什么耗时操作,我们直接在这里隐藏掉tip
if(0 == isFirst){
iv_float.setVisibility(View.GONE);
if(mRec != null && isFirst == 0 && iv_float.getVisibility() == View.VISIBLE){
ShowTipActivity.this.unregisterReceiver(mRec);
}
}
}
}
至此,我们的例子就做完了。这是一个比较简单的功能,当然可以在它显示和消失的时候加上动画,让效果看起来跟舒服。
DEMO下载地址:http://download.youkuaiyun.com/detail/yanbin1079415046/4555957