碎雨(二)

获取手机内存与SD卡容量

	@SuppressWarnings("deprecation")
	private String getSize(String path) {
		StatFs fs = new StatFs(path);
		int count = fs.getBlockCount();//得到block的总数
		long size = fs.getBlockSize();//得到每一个block的大小
		int availableBlocks = fs.getAvailableBlocks();//得到可用的block的数量
		String allSize = Formatter.formatFileSize(this, count * size);
		String avaSize = Formatter.formatFileSize(this, availableBlocks * size);
		return "所有:" + allSize + ",可用:" + avaSize;
	}
        对于其中的参数path,如果是sd卡,就用Environment.getExternalStorageDirectory().getPath().如果要获取手机内存,就用Environment.getDataDirectory().getPath()。

设置全屏

requestWindowFeature(Window.FEATURE_NO_TITLE);//无标题栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);// 全屏

以命令运行activity

        在开发中有可能想直接运行某个界面看效果。一般的做法就是修改清单文件中的LAUNCHER,但这样做不太方便,而且在合作开发时,容易导致混乱。这时可以通过命令行的形式直接运行指定的界面。
        首先为该界面对应的activity在清单文件中添加android:exported="true"属性(如果该activity配置了intent-filter该属性会自动设置为true),添加该属性为true后其他应用也可以启动指定的activity。
        其次在命令行中运行adb shell命令,然后调用am start -n命令,示例如下:
am start -n com.baigle.adapterdemo/com.baigle.adapterdemo.MainActivity
其中com.baigle.adapterdemo指的是应用的包名,而com.baigle.adapterdemo.MainActivity指的是要启动的activity。这样就可以直接启动对应的activity了。

am命令

        am是activity manager的简写。上面运用am启动了一个activity,am还可以进行许多操作。如 am startservice启动一个Service组件,am broadcast发送一个广播等。具体的可以通过直接在adb shell运行后运行am查看。
        运行am总少不了和intent的打交道,intent的具体写法如下:

比如运行am broadcast -a action1就相当于发送了一个Action为"action1"的广播。而am startservice -a action1 -c category1就相当于启动了一个Action为"action1",Category为"category1"的服务。

sp变化监听

当SharedPreferences中的数据发生变化时,可以进行监听。示例如下:
	sp = PreferenceManager.getDefaultSharedPreferences(this);//获取sp,这里是默认的
	listener = new OnSharedPreferenceChangeListener() {//sp变化监听的监听器
		public void onSharedPreferenceChanged(
				SharedPreferences sharedPreferences, String key) {
			if ("pref_syncConnectionType".equals(key)) {
				Preference preference = findPreference(key);
				preference.setSummary(sp.getString(key, "default"));
			}
		}
	};
	@Override
	protected void onResume() {//建议在onResume()中为sp注册监听
		super.onResume();
		sp.registerOnSharedPreferenceChangeListener(listener);
	}

	@Override
	protected void onPause() {//建议在onPause()中为sp注销监听
		super.onPause();
		sp.unregisterOnSharedPreferenceChangeListener(listener);
	}

        该方法主要是与Preference结合着使用,当用户更改了某一设置时,可以立即在界面上展示。

        之所以在onResume()与onPause()中注册与注销,是因为这两个方法界定了当前界面可操作与不可操作的边界

界面高亮提示

        在有些手机应用中,经常会出现在某一个界面上时会显示将某一个图标高亮显示,并且配上文字说明,而除了该图标之外的地方都是被蒙上一层阴影的。为实现该效果需要两步:(1)获得所要高度显示的组件的位置及大小,(2)用fragment蒙上原本的界面,并在高度组件处放置一个同样的组件。

示例如下:

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_above, container, false);
        TextView above = (TextView) view.findViewById(R.id.tv_above);
        //通过LayoutParams将传递的参数设置给要高亮显示的组件
        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(mWidth, mHeight);
        lp.leftMargin = mLeft - leftPadding;//-leftPadding是因为承载该fragment的ViewGroup本身距离屏幕有一定的距离
        lp.topMargin = mTop-38-leftPadding;//-38是减除状态栏的高度
        above.setLayoutParams(lp);
        return view;
    }
        在第一步中主要通过View.getLocationInWindow()方法获取到组件自身在屏幕上的位置,该方法将组件的左上角坐标赋值到传递的2维数组中,并且该位置是相对于屏幕的左上角而言,也即是:左上角的Y轴坐标是包含状态栏的。

禁用物理菜单键

	/**
	 * 关闭menu键
	 */
	public void closeMenu() {
		try {
			ViewConfiguration mconfig = ViewConfiguration.get(this);
			Field menuKeyField = ViewConfiguration.class
					.getDeclaredField("sHasPermanentMenuKey");
			if (menuKeyField != null) {
				menuKeyField.setAccessible(true);
				menuKeyField.setBoolean(mconfig, false);
			}
		} catch (Exception ex) {
		}
	}

res/raw与assets

        两者都是用来存放音频等文件的,但是raw目录下的文件系统会生成资源id:R.raw.file_name,但assets目录中的却不会。前者可以Resources.openRawResource();将对应的资源转换成InputStream,而后者只能通过AssetManager来读取。

兼容api

        如果在低版本上使用到了新版本的api,有两种方法:第一判断当前系统的api版本,只有满足调用新api的最低版本时才调用;第二种通过反射,如果获取不到新api中的方法,就意味着当前没办法调用新api,就需要通过旧api进行代替。例如:新版本的SharedPreferences.Editor提供了一个apply()方法,可以通过以下的方式进行判断:

	private void commit(Editor editor) {
		Class<Editor> clazz = SharedPreferences.Editor.class;
		try {
			Method method = clazz.getMethod("apply");
			method.invoke(editor);
		} catch (Exception e) {
			e.printStackTrace();
			editor.commit();//报异常说明没有该方法,就调用旧版本的commit()
		}
	}

加载GIF

        android对gif的显示是通过Movie类辅助完成的。4.0以上系统要显示gif时,必须关掉硬件加速,即在清单文件中配置android:hardwareAccelerated="false",或者调用View.setLayerType(LAYER_TYPE_SOFTWARE, new Paint());(据说此种方法适用于一部分手机)。

示例如下:

	private static class SampleView extends View {
		private Movie mMovie;
		private long mMovieStart;
		public SampleView(Context context) {
			super(context);
			setFocusable(true);
			InputStream is = context.getResources().openRawResource(
					R.drawable.animated_gif);
			mMovie = Movie.decodeStream(is);
		}

		@Override
		protected void onDraw(Canvas canvas) {
			canvas.drawColor(0xFFCCCCCC);
			long now = android.os.SystemClock.uptimeMillis();
			if (mMovieStart == 0) { // first time
				mMovieStart = now;
			}
			if (mMovie != null) {
				int dur = mMovie.duration();//获取gif持续时间
				if (dur == 0) {
					dur = 1000;
				}
				int relTime = (int) ((now - mMovieStart) % dur);
				mMovie.setTime(relTime);
				mMovie.draw(canvas, getWidth() - mMovie.width(), getHeight()
						- mMovie.height());
				invalidate();
			}
		}
	}
        上述代码首先通过Movie.decodeStream()生成与gif图片关联的Movie对象。通过Movie.setTime()设置当前显示gif应该要显示的时间,再调用Movie.draw()将当前时间对应的帧画在对应的canvas上。并通过不断调用onDraw()方法,画不同的帧从而使图片动起来。

        上面通过在onDraw()中调用invalidate(),可以不断重复执行onDraw(),从而保证了gif可以动起来。

图片模糊

        需要使用RenderScript进行向下兼容,而sdk本身就含有一个renderscript-v8.jar的jar包,直接可以使用。具体位置为:sdk\build-tools\sdk版本\renderscript\lib。示例具体代码如下:

public class BlurTools {
    private static final float BITMAP_SCALE = 0.4f;
    private static final float BLUR_RADIUS = 20f;
    public static Bitmap blurView(View v) {
        return blurBitmap(v.getContext(), getScreenshot(v));
    }
    public static Bitmap blurBitmap(Context ctx, Bitmap image) {
        int width = Math.round(image.getWidth() * BITMAP_SCALE);
        int height = Math.round(image.getHeight() * BITMAP_SCALE);
        Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false);
        Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
        RenderScript rs = RenderScript.create(ctx);
        ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
        Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
        theIntrinsic.setRadius(BLUR_RADIUS);
        theIntrinsic.setInput(tmpIn);
        theIntrinsic.forEach(tmpOut);
        tmpOut.copyTo(outputBitmap);
        return outputBitmap;
    }
    private static Bitmap getScreenshot(View v) {
        Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(b);
        v.draw(c);
        return b;
    }
}
        上述代码抄自stackoverflow,具体链接忘记了。

关联support源码

        sdk本身就含有各种support包,具体位置为sdk\extras\android\support。而在每一个support包下面都会有该包的源码,如:sdk\extras\android\support\v4\src。而在adt中关联源码方法如下:

        1,在libs目录下建立android-support-v4.jar.properties文件

        2,大该文件中添加"src = D:\\android-IDE\\sdk\\extras\\android\\support\\v4\\src",这里要注意:只写到src目录就可以,不要在结尾处添加分号,将单斜杠用“\\”替换掉。其实这里指定的就是v4源码的位置,也可以是别的路径。

        3,关闭工程,再打开就可以了。

        对于上面的第二步,v7包中的源码并不是和libs在一个目录下,它是和support目录同级的m2repository下,并且将源码打成jar了。因此properties的写法如下:src = sdk的路径\\sdk\\extras\\android\\m2repository\\com\\android\\support\\recyclerview-v7\\版本\\recyclerview-v7-21.0.3-sources.jar

打乱List集合中元素的顺序

        在某些时候需要打乱list集合中元素的顺序,可以通过以下方法进行操作:

		Collections.sort(null, new Comparator<Object>() {
			@Override
			public int compare(Object lhs, Object rhs) {
				//随机对调前后两个元素的
				return Math.random() > 0.5 ? 1 : -1;
			}
		});



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值