Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 安全衛士 第二天_注意事項

Android 安全衛士 第二天_注意事項

編輯:關於Android編程

Ctrl+T可以知道這個類的所有子類和父類。

如果你每個頁面都有相同的布局,那麼你就可以在 style文件裡面定義一個相同的style。

然後這樣就可以防止代碼的重復使用。

 

給你的控件設置

如果你設置的是marquee(跑馬燈)就是一個滾動效果 如果你設置為none就是不設置點。


獲取焦點:

android:focusable="true"
android:focusableInTouchMode="true"

————————

自定義控件:自動獲取焦點

1.自定義控件編寫流程
創建一個默認就能獲取焦點的TextView
1.創建一個類繼承至TextView,FocusTextView
2.重寫其構造方法

public class FocusTextView extends TextView {

	//使用在通過java代碼創建控件
	public FocusTextView(Context context) {
		super(context);
	}
	
	//由系統調用(帶屬性+上下文環境構造方法)
	public FocusTextView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	//由系統調用(帶屬性+上下文環境構造方法+布局文件中定義樣式文件構造方法)
	public FocusTextView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}
	
	//重寫獲取焦點的方法,由系統調用,調用的時候默認就能獲取焦點
	@Override
	public boolean isFocused() {//對應xml裡面的 android:focusable="true"和android:focusableInTouchMode="true"
		return true;
	}
}
4.使用過程

獲取當前類的全路徑名稱,作為xml中的標簽存在,其余屬性的使用方式和TextView一致

 

————————————————————————

2,GridView使用,和ListView使用方式類似
列數(3列)
數據填充(模塊名稱,模塊圖片)
數據適配器一致的

 

注意一點你設置適配器的時候,定義的布局文件中的控件一定要居中!!!

ImageView 有一個方法 setBackgroundResource(int id) 這個方法可以傳遞一個圖片的id

進來 然後設置給這個控件.

傳遞的id為R.drawable.xxxxxx

————————————

當你需要設置一個控件,當做一條線的時候。直接使用即可。

————————————————————————————

3,自定義組合控件
1.將已經編寫好的布局文件,抽取到一個類中去做管理,下次還需要使用此布局結構的時候,
直接使用組合控件對應的對象.
2.將組合控件的布局,抽取到單獨的一個xml中
3.通過一個單獨的類,去加載此段布局文件.

這裡注意一點,我們把一個view抽取出來,然後放到這個類裡面,這個類要繼承RelativeLayout。然後注意,我們要用這個類的構造方法,讓他三個構造方法都調用最後一個構造方法。然後使用view.inflate()去實現將一個布局文件裝換成一個view對象。

記住最後一個參數要寫this,因為我們需要將前面抽取出來的控件作為一個root(根),讓他加載到我們現在這個類裡面。

public class SettingItemView extends RelativeLayout {public SettingItemView(Context context) {

		this(context,null);
	}

	public SettingItemView(Context context, AttributeSet attrs) {
		this(context, attrs,0);
	}

	public SettingItemView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		//xml--->view	將設置界面的一個條目轉換成view對象,直接添加到了當前SettingItemView對應的view中
		View.inflate(context, R.layout.setting_item_view, this);

		//等同於以下兩行代碼
		/*View view = View.inflate(context, R.layout.setting_item_view, null);
		this.addView(view);*/
		
		//自定義組合控件中的標題描述
		TextView tv_title = (TextView) findViewById(R.id.tv_title);
		tv_des = (TextView) findViewById(R.id.tv_des);
		cb_box = (CheckBox) findViewById(R.id.cb_box);
		

	}



4.checkBox是否選中,決定SettingItemView是否開啟,isCheck(){return checkbox.isCheck()}方法
\

5.提供一個SettingItemView,切換選中狀態的方法setCheck(boolean isCheck)
在XML文件中設置

 

\

然後在SettingActivity中設置找到控件,並給他設置監聽

\

4,設置界面,事件傳遞過程
SettingActivity對應布局文件的跟布局獲取點擊事件
此事件傳遞給SettingItemView

1.點擊在SettingItemView非CheckBox區域,事件就由SettingItemView去做響應
2.點擊在SettingItemView中CheckBox區域,事件就由SettingItemView傳遞給CheckBox,由CheckBox去做響應

CheckBox響應當前的點擊事件,則SettingItemView就不能再去響應此事件,不能調用onClick方法,去改變狀態

這個是第一種方式:

讓我們的外部控件事件傳遞給內部控件,然後內部控件不去響應事件,在回傳給外部控件。

第二種方式:

讓我們的事件直接不能傳遞給內部控件,只能在外部控件。這個要去重寫事件響應的API

這裡我們使用第一種方式。

\

解決此問題的方案為:不讓checkBox響應點擊事件

_____________________________________

sputil類:

用來保存一些配置。

比如保存你的checkBox的勾選情況,下次進來的時候可以自動使用上次的勾選。

public class SpUtil {

	private static SharedPreferences sp;
	/**
	 * 寫入boolean變量至sp中
	 * @param ctx	上下文環境
	 * @param key	存儲節點名稱
	 * @param value	存儲節點的值 boolean
	 */
	public static void putBoolean(Context ctx,String key,boolean value){
		//(存儲節點文件名稱,讀寫方式)
		if(sp == null){
			sp = ctx.getSharedPreferences("config", Context.MODE_PRIVATE);
		}
		sp.edit().putBoolean(key, value).commit();
	}
	/**
	 * 讀取boolean標示從sp中
	 * @param ctx	上下文環境
	 * @param key	存儲節點名稱
	 * @param defValue	沒有此節點默認值
	 * @return		默認值或者此節點讀取到的結果
	 */
	public static boolean getBoolean(Context ctx,String key,boolean defValue){
		//(存儲節點文件名稱,讀寫方式)
		if(sp == null){
			sp = ctx.getSharedPreferences("config", Context.MODE_PRIVATE);
		}
		return sp.getBoolean(key, defValue);
	}

這裡有一個問題就是。

如果你在其他類調用這個類的方法的時候。

                                //獲取已有的開關狀態,用作顯示
                               boolean open_update = SpUtil.getBoolean(this, ConstantValue.OPEN_UPDATE, false);

		//是否選中,根據上一次存儲的結果去做決定
		siv_update.setCheck(open_update);

這裡我們在傳遞key的時候。因為key會復用所以我們直接用一個Constant類,來保存這些常量。

public class ConstantValue {

	/**
	 * 是否開啟更新的key
	 */
	public static final String OPEN_UPDATE = "open_update";
	
	/**
	 * 是否設置密碼key
	 */
	public static final String MOBILE_SAFE_PSD = "mobile_safe_psd";
}

————————————————————————————

注意一個問題:

private void initUpdate() {

		final SettingItemView siv_update = (SettingItemView) findViewById(R.id.siv_update);
		
		//獲取已有的開關狀態,用作顯示
		boolean open_update = SpUtil.getBoolean(this, ConstantValue.OPEN_UPDATE, false);
		//是否選中,根據上一次存儲的結果去做決定
		siv_update.setCheck(open_update);
		
		siv_update.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				//如果之前是選中的,點擊過後,變成未選中
				//如果之前是未選中的,點擊過後,變成選中
				
				//獲取之前的選中狀態
				boolean isCheck = siv_update.isCheck();
				//將原有狀態取反,等同上訴的兩部操作
				siv_update.setCheck(!isCheck);
				//將取反後的狀態存儲到相應sp中
				SpUtil.putBoolean(getApplicationContext(), ConstantValue.OPEN_UPDATE,!isCheck);
	
			}
		});
我們這裡在onclicklistener()

 

裡面去保存isCheck的狀態的時候 調用SpUtil類的時候傳遞進去的context 不能是this

因為在

new OnClickListener()

 

這個內部類裡面的this 是這個類的對象。

我們需要的context是activity裡面的對象。所以我們需要用getApplicationContext();

_________________________________________

mHandler.sendMessageDelayed(msg, 4000);
//在發送消息4秒後去處理,ENTER_HOME狀態碼指向的消息
mHandler.sendEmptyMessageDelayed(ENTER_HOME, 4000);

這兩個方法就是延時的去處理消息,不是延時去發送消息.

_______________________________________________________________

5,自定義屬性,(設置中心,有多個條目,在復用SettingItemView的時候,每一個條目對應的標示,描述內容都不一致)
1.查看源碼,定義屬性時候做法
sdk所在目錄\platforms\android-16\data\res\values\attrs.xml
2.給SettingItemView定義屬性,工程res\values\attrs.xml
3.自定義屬性的使用

Android之所以能用控件的屬性,比如是因為我們定義了命名空間:xmlns:android="http://schemas.android.com/apk/res/android"。

這樣就相當於連接到了這個文件的目錄下定義好的屬性。

所以我們要使用自定義的屬性也需要給它命名空間。

定義名空間namespace
mobilesafe替換掉原有android
com.itheima.mobilesafe74必須這樣編寫,替換掉了android,代表當前應用自定義屬性
xmlns:mobilesafe="http://schemas.android.com/apk/res/com.itheima.mobilesafe74"


xmlns:mobilesafe="http://schemas.android.com/apk/res/com.itheima.mobilesafe74"
android:id="@+id/siv_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
mobilesafe:destitle="自動更新設置"
mobilesafe:desoff="自動更新已關閉"
mobilesafe:deson="自動更新已開啟">
4.獲取屬性值
mobilesafe:destitle="自動更新設置"
mobilesafe:desoff="自動更新已關閉"
mobilesafe:deson="自動更新已開啟"
以上的是哪個屬性都需要給自定義組合控件(SettingItemView)內部的兩個TextView去使用,獲取屬性值

 

	//通過屬性索引獲取屬性名稱&屬性值
	for(int i=0;i


5.將獲取的屬性值,設置給title,des

des根據是否點中決定

true deson

false desoff

public class SettingItemView extends RelativeLayout {

	private static final String NAMESPACE = "http://schemas.android.com/apk/res/com.itheima.mobilesafe74";
	private static final String tag = "SettingItemView";
	private CheckBox cb_box;
	private TextView tv_des;
	private String mDestitle;
	private String mDesoff;
	private String mDeson;

	public SettingItemView(Context context) {
		this(context,null);
	}

	public SettingItemView(Context context, AttributeSet attrs) {
		this(context, attrs,0);
	}

	public SettingItemView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		//xml--->view	將設置界面的一個條目轉換成view對象,直接添加到了當前SettingItemView對應的view中
		View.inflate(context, R.layout.setting_item_view, this);

		//等同於以下兩行代碼
		/*View view = View.inflate(context, R.layout.setting_item_view, null);
		this.addView(view);*/
		
		//自定義組合控件中的標題描述
		TextView tv_title = (TextView) findViewById(R.id.tv_title);
		tv_des = (TextView) findViewById(R.id.tv_des);
		cb_box = (CheckBox) findViewById(R.id.cb_box);
		
		//獲取自定義以及原生屬性的操作,寫在此處,AttributeSet attrs對象中獲取
		initAttrs(attrs);
		//獲取布局文件中定義的字符串,賦值給自定義組合控件的標題
		tv_title.setText(mDestitle);
	}
	
	/**
	 * 返回屬性集合中自定義屬性屬性值
	 * @param attrs	構造方法中維護好的屬性集合
	 */
	private void initAttrs(AttributeSet attrs) {
		/*//獲取屬性的總個數
		Log.i(tag, "attrs.getAttributeCount() = "+attrs.getAttributeCount());
		//獲取屬性名稱以及屬性值
		for(int i=0;i

 

注意事項:當我們需要重寫一個自定義控件的自定義屬性的時候。

我們需要在這個工程的values文件下面創一個attrs.xml

————————————————————————————————

6,自定義對話框

\ 這裡我們同理用spUtil來保存密碼,將key設置為常量類裡面的常量。即可

\

自定義對話框步驟:

第一步我們new出對話框的Builder對象。

然後因為我們要定義自己的布局對話框界面。

所以第二步我們要創建一個對話框。

第三步就是調用setView方法,去使用一個布局文件。

就是使用xml---->view對象(使用infate)

技巧:TextUtils.isEmpty(str) 這個方法可以判斷str是否為""(空字符串) 或者為null

\ 這裡會出現button空指針異常。因為你直接使用findViewById是 在當前控件指定的布局文件中去找控件。

但是你現在要使用的button 是在view中的。所以我們需要使用view.findviewbyid.

 

	/**
	 * 設置密碼對話框
	 */
	private void showSetPsdDialog() {
		//因為需要去自己定義對話框的展示樣式,所以需要調用dialog.setView(view);
		//view是由自己編寫的xml轉換成的view對象xml----->view
		Builder builder = new AlertDialog.Builder(this);
		final AlertDialog dialog = builder.create();
		
		final View view = View.inflate(this, R.layout.dialog_set_psd, null);
		//讓對話框顯示一個自己定義的對話框界面效果
		dialog.setView(view);
		dialog.show();
		
		Button bt_submit = (Button) view.findViewById(R.id.bt_submit);
		Button bt_cancel = (Button) view.findViewById(R.id.bt_cancel);
		
		bt_submit.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				EditText et_set_psd = (EditText) view.findViewById(R.id.et_set_psd);
				EditText et_confirm_psd = (EditText)view.findViewById(R.id.et_confirm_psd);
				
				String psd = et_set_psd.getText().toString();
				String confirmPsd = et_confirm_psd.getText().toString();
				
				if(!TextUtils.isEmpty(psd) && !TextUtils.isEmpty(confirmPsd)){
					if(psd.equals(confirmPsd)){
						//進入應用手機防盜模塊,開啟一個新的activity
						Intent intent = new Intent(getApplicationContext(), TestActivity.class);
						startActivity(intent);
						//跳轉到新的界面以後需要去隱藏對話框
						dialog.dismiss();
						
						SpUtil.putString(getApplicationContext(), ConstantValue.MOBILE_SAFE_PSD, psd);
					}else{
						ToastUtil.show(getApplicationContext(),"確認密碼錯誤");
					}
				}else{
					//提示用戶密碼輸入有為空的情況
					ToastUtil.show(getApplicationContext(), "請輸入密碼");
				}
			}
		});
		
		bt_cancel.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				dialog.dismiss();
			}
		});
	}

Eclipse快捷鍵:Ctrl+D 快速刪除一行代碼。


6,密碼加密(了解)

 


md5加密:將字符串轉換成 32位的字符串(16進制字符(0~f)) 不可逆
 

import java.beans.Encoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


public class Md5Util {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//加鹽
		String psd = "123"+"abc";
		encoder(psd);
	}

	/**給指定字符串按照md5算法去加密
	 * @param psd	需要加密的密碼
	 */
	private static void encoder(String psd) {
		try {
			//1,指定加密算法類型
			MessageDigest digest = MessageDigest.getInstance("MD5");
			//2,將需要加密的字符串中轉換成byte類型的數組,然後進行隨機哈希過程
			byte[] bs = digest.digest(psd.getBytes());
//			System.out.println(bs.length);
			//3,循環遍歷bs,然後讓其生成32位字符串,固定寫法
			//4,拼接字符串過程
			StringBuffer stringBuffer = new StringBuffer();
			for (byte b : bs) {
				int i = b & 0xff;
				//int類型的i需要轉換成16機制字符
				String hexString = Integer.toHexString(i);
//				System.out.println(hexString);
				if(hexString.length()<2){
					hexString = "0"+hexString;
				}
				stringBuffer.append(hexString);
			}
			//5,打印測試
			System.out.println(stringBuffer.toString());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
	}
}

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved