android锁屏页面的实现

android的锁屏页面有两种方法实现;

可参考:http://blog.csdn.net/yangxi_pekin/article/details/50456763

http://blog.csdn.net/yangxi_pekin/article/details/50456763

http://blog.csdn.net/u010696525/article/details/51445515


我参考了他们,写的是一个activity页面当做锁屏页面


1.程序运行后开启一个管理锁屏页面的服务

//开启服务,开启锁屏界面
		startService(new Intent(MainActivity.this, LockScreenService.class));

2.在这个服务中去开启锁屏页面

public class LockScreenService extends Service {

	
	
	//屏幕熄灭的广播
	private BroadcastReceiver receiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			if (intent.getAction() == Intent.ACTION_SCREEN_OFF) {
				Intent lockScreenIntent = new Intent(LockScreenService.this,LockScreenActivity.class);
				lockScreenIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				if (!BaseApplication.getInstance().getParam(Params.IS_FORBID, false)) {
					startActivity(lockScreenIntent);
				}
			}
		}
	};
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		logger.debug("开启锁屏服务");
		return START_STICKY;
	};
	
	@Override
	public void onCreate() {
		IntentFilter filter = new IntentFilter();
		filter.addAction(Intent.ACTION_SCREEN_OFF);
		registerReceiver(receiver, filter);
	}

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}
	
	@Override
	public void onDestroy() {
		unregisterReceiver(receiver);
		super.onDestroy();

		Intent localIntent = new Intent();  
		localIntent.setClass(this, LockScreenService.class); //销毁时重新启动Service  
		this.startService(localIntent);
	}

}

3.锁屏页面

public class LockScreenActivity extends BaseActivity {
	
	
	/**左右滑动的监听*/
	private final class OnSildingFinishListenerImplementation implements
			OnSildingFinishListener {
		@Override
		public void onSildingForward() {
			LockScreenActivity.this.finish();
		}

		@Override
		public void onSildingBack() {
			LockScreenActivity.this.finish();
		}
	}
	
	
	ImageView iv_right_slip_anim;
	public static Handler myHandler = new Handler();
	private boolean isSpeaking = false;
	
	@Override
	public int getLayoutResId() {
		getWindow().addFlags(
				WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
						| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);//这句话必须写在前面

		return R.layout.activity_lockscreen;
	}

	@Override
	public void initView() {
		Bitmap bitmap = BitmapUtil.decodeSampledBitmapFromResource(getResources(), R.drawable.lockscreen_bg, 200, 400);
		Drawable drawable = BitmapUtil.bitmapToDrawable(bitmap);
		slf.setBackground(drawable);//设置了锁屏页面的背景色,根据自己的需要进行设置
	

		slf.setEnableLeftSildeEvent(true);
		slf.setEnableRightSildeEvent(false);
		
		setRightSlipAnim();
		
	}

	
	@Override
	public void initListener() {
		
		slf.setOnSildingFinishListener(new OnSildingFinishListenerImplementation());
		
	}

	@Override
	public void initData() {
		// TODO Auto-generated method stub

	}

	@Override
	public void doOtherDestroy() {
		
	}

	
	
	private void setRightSlipAnim() {
		iv_right_slip_anim.setImageResource(R.anim.lockscreen_right_slip);
		AnimationDrawable  animationDrawable = (AnimationDrawable) iv_right_slip_anim.getDrawable();
		animationDrawable.start();
	}

	
	@Override
	public void onBackPressed() {
		// 不做任何事,为了屏蔽back键
	}
在这个页面注册滑动监听,需要页面跟着手指一起移动,这里用到了一个自定义的布局,作为activity的头布局


4.我的activity的布局文件,头布局要用自定义的布局

<?xml version="1.0" encoding="utf-8"?>
<***.view.SildingFinishLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/sfl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/black">
    
    。。。。。。。。。
        
</***.SildingFinishLayout>

5.自定义的可以滑动的布局

/**
 * 自定义可以滑动的RelativeLayout, 类似于IOS的滑动删除页面效果,当我们要使用
 * 此功能的时候,需要将该Activity的顶层布局设置为SildingFinishLayout,
 */
public class SildingFinishLayout extends RelativeLayout{
	


	private final String TAG = SildingFinishLayout.class.getName();
	
	/**
	 * SildingFinishLayout布局的父布局
	 */
	private ViewGroup mParentView;
	
	/**
	 * 滑动的最小距离
	 */
	private int mTouchSlop;
	/**
	 * 按下点的X坐标
	 */
	private int downX;
	/**
	 * 按下点的Y坐标
	 */
	private int downY;
	/**
	 * 临时存储X坐标
	 */
	private int tempX;
	/**
	 * 滑动类
	 */
	private Scroller mScroller;
	/**
	 * SildingFinishLayout的宽度
	 */
	private int viewWidth;
	/**
	 * 记录是否正在滑动
	 */
	private boolean isSilding;
	
	private OnSildingFinishListener onSildingFinishListener;
	
	private boolean enableLeftSildeEvent = true; //是否开启左侧切换事件
	private boolean enableRightSildeEvent = true; // 是否开启右侧切换事件
	private int size ; //按下时范围(处于这个范围内就启用切换事件,目的是使当用户从左右边界点击时才响应)
	private boolean isIntercept = false; //是否拦截触摸事件
	private boolean canSwitch;//是否可切换
	private boolean isSwitchFromLeft = false; //左侧切换
	private boolean isSwitchFromRight = false; //右侧侧切换
	
	public SildingFinishLayout(Context context) {
		super(context);
		init(context);
	}
	public SildingFinishLayout(Context context, AttributeSet attrs) {
		super(context, attrs, 0);
		init(context);
	}
	public SildingFinishLayout(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(context);
	}

	private void init(Context context) {
		mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
		Log.i(TAG, "设备的最小滑动距离:" + mTouchSlop);
		mScroller = new Scroller(context);
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		if (changed) {
			// 获取SildingFinishLayout所在布局的父布局
			mParentView = (ViewGroup) this.getParent();
			viewWidth = this.getWidth();
			size = viewWidth;
		}
		Log.i(TAG, "viewWidth=" + viewWidth);
	}
	
	
	public void setEnableLeftSildeEvent(boolean enableLeftSildeEvent) {
		this.enableLeftSildeEvent = enableLeftSildeEvent;
	}
	
	
	public void setEnableRightSildeEvent(boolean enableRightSildeEvent) {
		this.enableRightSildeEvent = enableRightSildeEvent;
	}
	

	/**
	 * 设置OnSildingFinishListener, 在onSildingFinish()方法中finish Activity
	 * 
	 * @param onSildingFinishListener
	 */
	public void setOnSildingFinishListener(
			OnSildingFinishListener onSildingFinishListener) {
		this.onSildingFinishListener = onSildingFinishListener;
	}
	
	//是否拦截事件,如果不拦截事件,对于有滚动的控件的界面将出现问题(相冲突)
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		float downX = ev.getRawX();
		Log.i(TAG, "downX =" + downX + ",viewWidth=" + viewWidth);
		if(enableLeftSildeEvent && downX < size){
			Log.e(TAG, "downX 在左侧范围内 ,拦截事件");
			isIntercept = true;
			isSwitchFromLeft = true;
			isSwitchFromRight = false;
			return false;
		}else if(enableRightSildeEvent && downX > (viewWidth - size)){
//			Log.i(TAG, "downX 在右侧范围内 ,拦截事件");
			isIntercept = true;
			isSwitchFromRight = true;
			isSwitchFromLeft = false;
			return true;
		}else{
//			Log.i(TAG, "downX 不在范围内 ,不拦截事件");
			isIntercept = false;
			isSwitchFromLeft = false;
			isSwitchFromRight = false;
		}
		return super.onInterceptTouchEvent(ev);
	}


	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if(!isIntercept){//不拦截事件时 不处理
			return false;
		}
		switch (event.getAction()){
		case MotionEvent.ACTION_DOWN:
			downX = tempX = (int) event.getRawX();
			downY = (int) event.getRawY();
			break;
		case MotionEvent.ACTION_MOVE:
			int moveX = (int) event.getRawX();
			int deltaX = tempX - moveX;	
			tempX = moveX;
			if (Math.abs(moveX - downX) > mTouchSlop && Math.abs((int) event.getRawY() - downY) < mTouchSlop) {
				isSilding = true;
			}
			
			Log.e(TAG, "scroll deltaX=" + deltaX);			
			if(enableLeftSildeEvent){//左侧滑动
				if (moveX - downX >= 0 && isSilding) {
					mParentView.scrollBy(deltaX, 0);
				}
			}
			
			if(enableRightSildeEvent){//右侧滑动
				if (moveX - downX <= 0 && isSilding) {
					mParentView.scrollBy(deltaX, 0);
				}
			}
			
			Log.i(TAG + "/onTouchEvent", "mParentView.getScrollX()=" + mParentView.getScrollX());
			break;
		case MotionEvent.ACTION_UP:
			isSilding = false;
			//mParentView.getScrollX() <= -viewWidth / 2  ==>指左侧滑动
			//mParentView.getScrollX() >= viewWidth / 2   ==>指右侧滑动
			if (mParentView.getScrollX() <= -viewWidth / 2 || mParentView.getScrollX() >= viewWidth / 2) {
				canSwitch = true;
				if(isSwitchFromLeft){
					scrollToRight();
				}
				
				if(isSwitchFromRight){
					scrollToLeft();
				}
			} else {
				scrollOrigin();
				canSwitch = false;
			}
			break;
		}
		return true;
	}
	
	
	/**
	 * 滚动出界面至右侧
	 */
	private void scrollToRight() {
		final int delta = (viewWidth + mParentView.getScrollX());
		// 调用startScroll方法来设置一些滚动的参数,我们在computeScroll()方法中调用scrollTo来滚动item
		mScroller.startScroll(mParentView.getScrollX(), 0, -delta + 1, 0, Math.abs(delta));
		postInvalidate();
	}
	
	/**
	 * 滚动出界面至左侧
	 */
	private void scrollToLeft() {
		final int delta = (viewWidth - mParentView.getScrollX());
		// 调用startScroll方法来设置一些滚动的参数,我们在computeScroll()方法中调用scrollTo来滚动item
		mScroller.startScroll(mParentView.getScrollX(), 0, delta - 1, 0, Math.abs(delta));//此处就不可用+1,也不卡直接用delta
		postInvalidate();
	}

	/**
	 * 滚动到起始位置
	 */
	private void scrollOrigin() {
		int delta = mParentView.getScrollX();
		mScroller.startScroll(mParentView.getScrollX(), 0, -delta, 0,
				Math.abs(delta));
		postInvalidate();
	}
	
	

	@Override
	public void computeScroll(){
		// 调用startScroll的时候scroller.computeScrollOffset()返回true,
		if (mScroller.computeScrollOffset()) {
			mParentView.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
			postInvalidate();

			if (mScroller.isFinished()) {
				if (onSildingFinishListener != null && canSwitch) {
					Log.i(TAG, "mScroller finish");
					if(isSwitchFromLeft){//回调,左侧切换事件
						onSildingFinishListener.onSildingBack();
					}
					
					if(isSwitchFromRight){//右侧切换事件
						onSildingFinishListener.onSildingForward();
					}
				}
			}
		}
	}
	

	public interface OnSildingFinishListener {
		public void onSildingBack();
		public void onSildingForward();
	}

}
这个布局可以用来分别监听向左、向右滑动,根据自己的需要来写。


6.在清单文件中对锁屏的activity的注册

<activity
            android:name="cn.zectec.ptt.activity.LockScreenActivity"
            android:launchMode="singleInstance"
			android:taskAffinity="cn.zectec.ptt.activity.lockscreen"           
            android:excludeFromRecents="true"
            android:noHistory="false"//之前设置的是true,发现锁屏页面会一次出现一次消失,就改成了false
            android:theme="@style/LockScreenBase"
            android:screenOrientation="portrait" />

style的样式:

<!-- 锁屏界面样式 -->
    <style name="LockScreenBase" parent="android:Theme.Light.NoTitleBar">
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:colorBackgroundCacheHint">@null</item>
        <item name="android:windowNoTitle">true</item>
    </style>
<!--         <item name="android:backgroundDimEnabled">false</item>
        <item name="android:windowAnimationStyle">@null</item>
        <item name="android:windowContentOverlay">@null</item> -->

这个样式可以根据自己的需求来设置。


思路:服务中注册屏幕熄灭广播,发现屏幕熄灭就开启锁屏页面,再次点亮屏幕,滑动锁屏页面,锁屏页面被销毁,进入程序主界面。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值