掌上快递之主界面篇(2)

概述

这是Fragment1的第二部分内容 侧滑栏,(主要效果是仿QQ效果)使用了github上的slidingmenu_librarygithub开源控件

效果图如下:

【1】内容区域会伴随菜单的出现而缩小

【2】侧滑菜单给人的感觉是隐藏在内容的后面,而不是拖出来的感觉

【3】侧滑菜单有一个缩放以及透明度的效果

然后就是简单的百度地图,和摇一摇显示小知识

掌上快递之主界面篇(2)_第1张图片掌上快递之主界面篇(2)_第2张图片掌上快递之主界面篇(2)_第3张图片


1、布局文件

include在fragment1的主布局文件R.layout.activity_main中      <include layout="@layout/left_slide" />

由于侧滑栏只是一个listview即可布局文件比较简单

<span style="font-family:Microsoft YaHei;font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/header"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:layout_gravity="center_horizontal"
        android:src="@drawable/slideledefheader" />

    <ListView
        android:id="@+id/leftslide_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="20dp"
        android:cacheColorHint="#00000000"
        android:footerDividersEnabled="false"
        android:gravity="center_horizontal"
        android:listSelector="@android:color/transparent" >
    </ListView>

</LinearLayout></span>

2、侧滑特效实现分析

那么我们如何能做到呢:

我们可以在滑动的时候,不断的改变内容区域的大小;如何改变呢?我们在菜单出现的整个过程中,不断记录菜单显示的宽度与其总宽度的比值,是个从0到1的过程,然后把0~1转化为1~0.7(假设内容区域缩小至0.7);不断去缩小内容区域;

上面已经可以得到0到1的这个值了,那么缩放和透明度的动画就不在话下了;

我们使用的HorizontalScrollView,然后水平放置了菜单和内容,如何让菜单可以隐藏到内容的后面呢?其实也比较简单,在菜单出现的过程中,不断设置菜单的x方向的偏移量;0的时候完全隐藏,0.3的时候,隐藏x方向偏移量为0.7个宽度

主要代码在SlidingMenu.java中

<span style="font-family:Microsoft YaHei;font-size:14px;">	/**
	 * 滚动发生时
	 */
	@Override
	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		super.onScrollChanged(l, t, oldl, oldt);
		float scale = l * 1.0f / mMenuWidth; // 1 ~ 0

		/**
		 * 区别1:内容区域1.0~0.7 缩放的效果 scale : 1.0~0.0 0.7 + 0.3 * scale
		 * 
		 * 区别2:菜单的偏移量需要修改
		 * 
		 * 区别3:菜单的显示时有缩放以及透明度变化 缩放:0.7 ~1.0 1.0 - scale * 0.3 透明度 0.6 ~ 1.0 0.6+
		 * 0.4 * (1- scale) ;
		 * 
		 */
		float rightScale = 0.7f + 0.3f * scale;
		float leftScale = 1.0f - scale * 0.3f;
		float leftAlpha = 0.6f + 0.4f * (1 - scale);

		// 调用属性动画,设置TranslationX
		ViewHelper.setTranslationX(mMenu, mMenuWidth * scale * 0.8f);

		ViewHelper.setScaleX(mMenu, leftScale);
		ViewHelper.setScaleY(mMenu, leftScale);
		ViewHelper.setAlpha(mMenu, leftAlpha);
		// 设置content的缩放的中心点
		ViewHelper.setPivotX(mContent, 0);
		ViewHelper.setPivotY(mContent, mContent.getHeight() / 2);
		ViewHelper.setScaleX(mContent, rightScale);
		ViewHelper.setScaleY(mContent, rightScale);

	}
</span>



3、百度地图

关于获取百度地图秘钥和基本功能实现请见我的另一篇博文百度地图入门,地图部分做的比较简单,主要就是继承了BDLocationListener实现自己的定位(private class MyLocationListener implements BDLocationListener),然后使用附近搜索mPoiSearch
                        .searchNearby((new PoiNearbySearchOption())
                                .location(latLng).keyword("快递").radius(3000)
                                .pageNum(0));

<span style="font-family:Microsoft YaHei;font-size:14px;">package com.map;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationConfiguration.LocationMode;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.overlayutil.PoiOverlay;
import com.baidu.mapapi.search.core.CityInfo;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.poi.OnGetPoiSearchResultListener;
import com.baidu.mapapi.search.poi.PoiDetailResult;
import com.baidu.mapapi.search.poi.PoiNearbySearchOption;
import com.baidu.mapapi.search.poi.PoiResult;
import com.baidu.mapapi.search.poi.PoiSearch;
import com.baidu.mapapi.search.poi.PoiSortType;
import com.map.MyOrientationListener.OnOrientationListener;
import com.weimeijing.feigeshudi.R;

public class Baidu extends Activity {
	// 定义所需要的控件
	private MapView mMapView = null;
	private BaiduMap mBaiduMap = null;
	private Context context = null;
	// 定位相关的控件
	private LocationClient mLocationClient;
	private MyLocationListener mLocationListener;
	private boolean isFirstIn = true;
	// 记录经纬度
	private double mLatitude;
	private double mLongtitude;
	// 自定义定位图标
	private BitmapDescriptor mIconLocation;
	// 方向传感器
	private MyOrientationListener myOrientationListener;
	private float mCurrentX;
	private LocationMode mLocationMode;
	// poi
	private PoiSearch mPoiSearch = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		// 去除titlebar
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		// 在使用SDK各组件之前初始化context信息,传入ApplicationContext
		// 注意该方法要再setContentView方法之前实现
		SDKInitializer.initialize(getApplicationContext());
		// 加载地图布局文件
		setContentView(R.layout.baidumap);
		this.context = this;
		// 初始化定位
		iniLocation();
		// 获取地图控件引用
		initView();

		mBaiduMap.setMyLocationEnabled(true);
		if (!mLocationClient.isStarted())
			// 开启定位
			mLocationClient.start();
		// 开启方向传感器
		myOrientationListener.start();

	}

	private void iniLocation() {
		// 默认是普通模式
		mLocationMode = LocationMode.NORMAL;
		mLocationClient = new LocationClient(this);
		mLocationListener = new MyLocationListener();
		// 注册监听
		mLocationClient.registerLocationListener(mLocationListener);
		// 设置配置
		LocationClientOption option = new LocationClientOption();
		Toast.makeText(Baidu.this, "将显示您附近3000米内的快递点", Toast.LENGTH_LONG)
				.show();
		// 设置左边类型
		option.setCoorType("bd09ll");
		option.setIsNeedAddress(true);// 返回定位结果信息
		option.setOpenGps(true);
		// 设置一秒产生一次请求
		option.setScanSpan(2000);
		mLocationClient.setLocOption(option);
		// 初始化定位图标
		mIconLocation = BitmapDescriptorFactory
				.fromResource(R.drawable.navi_map_gps_locked);
		// 方向箭头监听
		myOrientationListener = new MyOrientationListener(context);
		myOrientationListener
				.setOnOrientationListener(new OnOrientationListener() {
					@Override
					public void onOrientationChanged(float x) {
						mCurrentX = x;
					}
				});

	}

	private void initView() {
		mMapView = (MapView) findViewById(R.id.id_bmapView);
		// 获得到地图
		mBaiduMap = mMapView.getMap();
		// 设置地图显示比例
		MapStatusUpdate msu = MapStatusUpdateFactory.zoomBy(5.0f);// 100米左右
		mBaiduMap.setMapStatus(msu);

	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		mPoiSearch.destroy();
		super.onDestroy();
		mMapView.onDestroy();
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		mMapView.onResume();
	}

	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		super.onStart();
		/*
		 * mBaiduMap.setMyLocationEnabled(true); if
		 * (!mLocationClient.isStarted()) // 开启定位 mLocationClient.start(); //
		 * 开启方向传感器 myOrientationListener.start();
		 */
	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		mMapView.onPause();
	}

	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		super.onStop();
		// 停止定位
		mBaiduMap.setMyLocationEnabled(false);
		mLocationClient.stop();
		// 停止方向传感器
		myOrientationListener.stop();

	}

	// 按钮菜单
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	// 菜单按钮的选择
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// 通过Item的ID选择用户选择按钮
		switch (item.getItemId()) {
		case R.id.id_map_commom:
			// 加载地图为普通模式
			mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
			break;

		case R.id.id_map_site:
			mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
			break;
		/*
		 * case R.id.id_map_location: centerToMyLocation(); break;
		 */
		case R.id.id_map_mode_common:
			mLocationMode = LocationMode.NORMAL;
			break;
		/*
		 * case R.id.id_map_mode_following: mLocationMode =
		 * LocationMode.FOLLOWING; break;
		 */
		case R.id.id_map_mode_compass:
			mLocationMode = LocationMode.COMPASS;
			break;

		default:
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	// 定位到我的位置
	private void centerToMyLocation() {
		LatLng latLng = new LatLng(mLatitude, mLongtitude);
		MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
		mBaiduMap.animateMapStatus(msu);
	}

	private class MyLocationListener implements BDLocationListener {

		// 定位成功之后的回调函数
		@Override
		public void onReceiveLocation(BDLocation location) {
			MyLocationData data = new MyLocationData.Builder() // 建造者模式
					.direction(mCurrentX)//
					.accuracy(location.getRadius())//
					.latitude(location.getLatitude())//
					.longitude(location.getLongitude())//
					.build();

			mBaiduMap.setMyLocationData(data);
			// 设置自定义图标
			MyLocationConfiguration config = new MyLocationConfiguration(
					mLocationMode, true, mIconLocation);
			mBaiduMap.setMyLocationConfigeration(config);

			// 更新经纬度
			mLatitude = location.getLatitude();
			mLongtitude = location.getLongitude();
			// 初始化Poi搜索
			mPoiSearch = PoiSearch.newInstance();
			mPoiSearch
					.setOnGetPoiSearchResultListener(new OnGetPoiSearchResultListener() {
						@Override
						public void onGetPoiResult(PoiResult result) {
							if (result == null
									|| result.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {
								return;
							}
							// 找到则显示覆盖物
							if (result.error == SearchResult.ERRORNO.NO_ERROR) {
								mBaiduMap.clear();
								PoiOverlay overlay = new MyPoiOverlay(mBaiduMap);
								mBaiduMap.setOnMarkerClickListener(overlay);
								overlay.setData(result);
								overlay.addToMap();
								overlay.zoomToSpan();
								return;
							}
						}

						// 点击覆盖物
						@Override
						public void onGetPoiDetailResult(PoiDetailResult result) {
							if (result.error != SearchResult.ERRORNO.NO_ERROR) {
								Toast.makeText(Baidu.this, "抱歉,未找到结果",
										Toast.LENGTH_SHORT).show();
							} else {
								Toast.makeText(
										Baidu.this,
										result.getName() + ": "
												+ result.getAddress(),
										Toast.LENGTH_SHORT).show();

								/*
								 * Toast.makeText(Baidu.this,
								 * "将显示您附近5000米内的快递点",
								 * Toast.LENGTH_LONG).show();
								 */

							}
						}
					});
			// mPoiSearch.setOnGetPoiSearchResultListener(this);
			/*
			 * LatLng latLng1 = new LatLng(location.getLatitude(),
			 * location.getLongitude());// 获取经纬度
			 */

			// 判断用户是否第一次进入地图
			if (isFirstIn) {
				LatLng latLng = new LatLng(location.getLatitude(),
						location.getLongitude());// 获取经纬度
				MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
				mBaiduMap.animateMapStatus(msu);
				isFirstIn = false;
				Toast.makeText(context, location.getAddrStr(),
						Toast.LENGTH_SHORT).show();
				<span style="color:#009900;">mPoiSearch
						.searchNearby((new PoiNearbySearchOption())
								.location(latLng).keyword("快递").radius(3000)
								.pageNum(0));</span>
			}
		}
	}

	private class MyPoiOverlay extends PoiOverlay {

		public MyPoiOverlay(BaiduMap baiduMap) {
			super(baiduMap);
			// TODO Auto-generated constructor stub
		}

	}

}
</span>

4、摇一摇

这个就更加简单了,主要是

【1】监听XYZ三个轴的加速度,onSensorChanged(SensorEvent event)

【2】handler异步处理事件

【3】shake_action();中用随机数代表触发时事件


<span style="font-family:Microsoft YaHei;font-size:14px;">package com.leftside;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;

import com.weimeijing.feigeshudi.R;

public class Shake extends Activity {
	private SensorManager sensorManager;
	private Vibrator vibrator;
	ImageView iv;
	MediaPlayer mp;
	boolean isPlay = false;
	private static final String TAG = "TestSensorActivity";
	private static final int SENSOR_SHAKE = 10;

	private TextView tv_shake1;
	private TextView tv_shake2;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.shake);
		mp = MediaPlayer.create(this, R.raw.shake);
		iv = (ImageView) findViewById(R.id.imageview);
		// 获取传感器管理服务
		sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
		vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);

		/* tv_shake1 = (TextView) findViewById(R.id.tv_shake1); */
		tv_shake2 = (TextView) findViewById(R.id.tv_shake2);

	}



	@Override
	protected void onResume() {
		super.onResume();
		if (sensorManager != null) {
			// 为系统的方向传感注册监听器
			sensorManager.registerListener(sensorEventListener,
					sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
					SensorManager.SENSOR_DELAY_NORMAL);
		}
	}

	@Override
	protected void onPause() {
		super.onPause();
		if (sensorManager != null) {
			// 取消监听器
			sensorManager.unregisterListener(sensorEventListener);
		}
		if (isPlay) {
			mp.stop();
			mp.release();
		}
	}

	/*
	 * 重力感应监听
	 */
	private SensorEventListener sensorEventListener = new SensorEventListener() {

		@Override
		public void onSensorChanged(SensorEvent event) {
			// 传感器信息改变时执行该方法
			float[] values = event.values;
			float x = values[0];// x轴方向的重力加速度,向右为正
			float y = values[1];// y轴方向的重力加速度,向前为正
			float z = values[2];// y轴方向的重力加速度,向前为正
			// 根据结果执行操作
			if (Math.abs(x) > 14 || Math.abs(y) > 16 || Math.abs(z) > 16) {
				isPlay = true;
				// mp.seekTo(0);
				vibrator.vibrate(200);
				// Handler 异步处理技术
				Message msg = new Message();
				msg.what = SENSOR_SHAKE;
				//mp.start();// 加这个会死机?
				handler.sendMessage(msg);
				Log.i(TAG, "x轴方向的重力加速度" + x + ";y轴方向的重力加速度" + y + ";z轴方向的重力加速度"
						+ z);
			}

		}

		@Override
		public void onAccuracyChanged(Sensor sensor, int accuracy) {

		}
	};
	Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			//mp.start();// 加这个会死机?
			switch (msg.what) {
			case SENSOR_SHAKE:
				int i = 0;
				//手动延时
				while (true) {
					i++;
					if (i == 800)
						break;
				}
				shake_action();
				break;

			default:
				break;
			}
		}

		private void shake_action() {
			/* tv_shake1.setVisibility(View.VISIBLE); */
			int id = (int) (Math.random() * 13 + 1);
			switch (id) {
			case 1:

				tv_shake2.setText(R.string.shake1);
				break;
			case 2:
				tv_shake2.setText(R.string.shake2);
				break;
			case 3:
				tv_shake2.setText(R.string.shake3);
				break;
			case 4:
				tv_shake2.setText(R.string.shake4);
				break;
			case 5:
				tv_shake2.setText(R.string.shake5);
				break;
			case 6:
				tv_shake2.setText(R.string.shake6);
				break;
			case 7:
				tv_shake2.setText(R.string.shake7);
				break;
			case 8:
				tv_shake2.setText(R.string.shake8);
				break;
			case 9:
				tv_shake2.setText(R.string.shake9);
				break;
			case 10:
				tv_shake2.setText(R.string.shake10);
				break;
			case 11:
				tv_shake2.setText(R.string.shake11);
				break;
			case 12:
				tv_shake2.setText(R.string.shake12);
				break;
			case 13:
				tv_shake2.setText(R.string.shake13);
				break;

			default:
				break;
			}
			tv_shake2.setVisibility(View.VISIBLE);

		}
	};

}
</span>

5、知识总结

【1】slidingmenu_library开源控件的使用

【2】百度地图

【3】传感器

【4】handler的使用



你可能感兴趣的:(android)