当前位置:  编程技术>移动开发
本页文章导读:
    ▪两台PAD 同一界面式样的调整        两台PAD 同一界面样式的调整 做项目的过程中,有可能同时有好几台机器做测试,如果做到分辨率适配呢一般我觉得影响界面样式不一样的主要有2个因素,分辨率即(高度和宽带),密度以下我.........
    ▪ CountDownButton:记时的Button        CountDownButton:倒计时的Button 基于倒计时的TextView而写,没什么特别的,代码: import android.content.Context; import android.os.Handler; import android.os.SystemClock; import android.util.AttributeSet; import android.widget.Bu.........
    ▪ Activity的LaunchMode跟taskAffinity       Activity的LaunchMode和taskAffinity 做项目到现在都一直没有理解LaunchMode有什么用,或许根本就没真正花心思去看,所以今天把这部分整理下。   设置Activity的LaunchMode属性可以决定这个Activity是.........

[1]两台PAD 同一界面式样的调整
    来源: 互联网  发布时间: 2014-02-18
两台PAD 同一界面样式的调整
做项目的过程中,有可能同时有好几台机器做测试,如果做到分辨率适配呢
一般我觉得影响界面样式不一样的主要有2个因素,分辨率即(高度和宽带),密度

以下我就具体说下,我项目中具体的2台测试机型为
1,lenovo A1_7  分辨率1024*600  密度1.5  一英寸多少像素(dpi)240[密度x160]
2,lenovo V2007 分辨率1216*800  密度1.33  一英寸多少像素(dpi)213[密度x160]

dpi240,应该属于~240dpi范围, hdpi
~160dpi,mdpi范围
~120dpi,ldpi

那么第一台属于hdpi,但是第二台213,显然没办法通过hdpi,mdpi,ldpi区分

解决的办法就是分别建立valus-1024x600和values-1216x800,然后放入对应的样式文件,该问题即成功解决

    
[2] CountDownButton:记时的Button
    来源: 互联网  发布时间: 2014-02-18
CountDownButton:倒计时的Button


基于倒计时的TextView而写,没什么特别的,代码:
import android.content.Context;
import android.os.Handler;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.widget.Button;

public class CountDownButton extends Button {
	private Runnable mTicker;
	private Handler mHandler;

	private boolean mTickerStopped = false;
	
	private OnCountDownListener onCountDownListener;//监听回调
	private int count=10;//倒计时的步数
	private CharSequence text;//原始文字
	public CountDownButton(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		init();
	}
	public CountDownButton(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		init();
	}
	public CountDownButton(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
		init();
	}

	private void init(){
		text=getText();
	}
	@Override
	protected void onDetachedFromWindow() {
		super.onDetachedFromWindow();
		mTickerStopped = true;
	}
	@Override
	protected void onAttachedToWindow() {
		mTickerStopped = false;
		super.onAttachedToWindow();
		mHandler = new Handler();

		/**
		 * requests a tick on the next hard-second boundary
		 */
		mTicker = new Runnable() {
			public void run() {
				if (mTickerStopped)
					return;
				if(count<=0){
					if (onCountDownListener != null)
						onCountDownListener.onFinish();
					return;
				}
				count--;
				setText(text+"("+count+")");
				if (onCountDownListener != null)
					onCountDownListener.onTick();
				invalidate();
				long now = SystemClock.uptimeMillis();
				long next = now + (1000 - now % 1000);
				mHandler.postAtTime(mTicker, next);
			}
		};
		mTicker.run();
	}
	
	public interface OnCountDownListener {
		public void onFinish();

		public void onTick();
	}

	public void setOnCountDownListener(OnCountDownListener onCountDownListener) {
		this.onCountDownListener = onCountDownListener;
	}

	public int getCount() {
		return count;
	}
	public void setCount(int count) {
		if(count<0){
			this.count=0;
                        return;
		}
		this.count = count;
	}
}


用法:
CountDownButton btn = (CountDownButton) findViewById(R.id.btn);
		btn.setCount(60);
		btn.setOnCountDownListener(new CountDownButton.OnCountDownListener() {

			@Override
			public void onTick() {
				// TODO Auto-generated method stub
				Log.i("tag", "onTick");
			}

			@Override
			public void onFinish() {
				// TODO Auto-generated method stub
				Log.i("tag", "onFinish");
			}
		});

没了!

用自定义Button实现ToggleButton
点击一个按钮,就会有按下的效果,再点击会弹起,实现一个类似ToggleButton的功能。
import android.content.Context; 
import android.util.AttributeSet; 
import android.widget.Button;

public class MyTextButton extends Button {

    private boolean checked;

    public MyTextButton(Context context, AttributeSet attrs) { 
        super(context, attrs); 
    }

    @Override 
    public boolean performClick() { 
        this.checked = !this.checked; 
        return super.performClick(); 
    }

    @Override 
    protected int[] onCreateDrawableState(int extraSpace) { 
        if (!checked) { 
            return Button.PRESSED_ENABLED_SELECTED_STATE_SET; 
        } else { 
            return Button.EMPTY_STATE_SET; 
        } 
    } 
}




    
[3] Activity的LaunchMode跟taskAffinity
    来源: 互联网  发布时间: 2014-02-18
Activity的LaunchMode和taskAffinity

做项目到现在都一直没有理解LaunchMode有什么用,或许根本就没真正花心思去看,所以今天把这部分整理下。

  设置Activity的LaunchMode属性可以决定这个Activity是和当前Task保持关联,还是说每次运行这个Activity是新建一个实例,还是保持单例。

  Task和Back Stack简介

  task是一组Activities的集合,一组Activities被Stack(back stack)所管理。

  在一个应用中,有3个activities,分别是activity1,activity2,activity3,首先activity1被start,此时,如果应用没有创建task则创建,并把activity1压入栈顶,activity1触发onCreate->onStart->onResume。

  

  接着activity1转向到activity2时,activity1先触发onPause,activity2触发onCreate->onStart->onResume,然后activity1触发onPause->onStop,activity2压入栈顶。

  

  以此类推,activity2转向activity3也是一样的步骤。那么当前栈顶是activity3。

  

  当我们按下手机上的返回键时,栈顶的activity3触发onPause,activity2需要从状态stop到pause,所以触发了onPause->onStart->onResume,activity3触发onStop->onDestory,因为activity3从栈顶弹出,所以触发onDestory,此时,activity2在栈顶。

  

  如果继续按返回键,当前栈顶的activity弹出并被destory,直到home界面。当所有的activity都弹出了,这个task也就消亡了。

  当开始一个新的task时,前一个task被设置为后台,在后台,所有的activity都处理stop状态,但是back stack保留了所有后台activity的状态信息,只是丢失了焦点。

  反复的在两个activity之间切换,activity会产生多个独立的实例。

  

  查阅有关Activity生命周期更多说明。

  两种方式设置LaunchMode属性

  1.  在 manifest文件中设置

<activity android:name=".activity.ActivityA"
        android:launchMode="standard">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

  2.  使用Intent flags设置

Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(ActivityA.this, ActivityB.class);
startActivity(intent);

  四种LaunchMode说明

  standard

   不做任何设置,默认模式就是standard,activity在每次start时,都会有一个新的实例被task管理。下面看下代码实例。

//ActivityA.java
Intent intent = new Intent();
intent.setClass(ActivityA.this, ActivityB.class);
startActivity(intent);

//ActivityB.java
Intent intent = new Intent();
intent.setClass(ActivityB.this, ActivityA.class);
startActivity(intent);

 

 操作1:在ActivityA(蓝)和ActivityB(绿)之间重复切换,按返回键推到home界面。

  可以发现(蓝色86和绿色79的taskID)ActivityA和ActivityB都在同一个task,并且每次resume的实例都是不一样的。这说明在一个activity可以有多个实例在同一个task中。

  在按返回按键时,将依次弹出stack。

  singleTop

  和standard一样,可以多次实例,但,如果处于当前栈顶并且接受到一个与当前activity一样类型的intent,那么不会创建一个新实例,而是触发onNewIntent()事件。

//ActivityA.java
Intent intent = new Intent();
intent.setClass(ActivityA.this, ActivityA.class);
startActivity(intent);

@Override
protected void onNewIntent(Intent intent) {
    logger.d("onNewIntent " + this.hashCode() + " taskID "
                + this.getTaskId());
    super.onNewIntent(intent);
}
<activity android:name=".activity.ActivityA" android:label="ActivityA"
            android:launchMode="singleTop">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

操作1:点击ActivityA上的按钮

  发现当点击按钮是ActivityA->onPause->onNewIntent->onResume,没有新建新的实例(蓝62)。

  这个模式在这个场景下比较有用,比如:如果有一个其他的应用想启动你的Activity(launch mode为singleTop),而你当前的Activity正好在栈顶,那么就会调用到onNewIntent方法。原文贴上:If an instance of the activity already exists at the top of the current task, the system routes the intent to that instance through a call to its onNewIntent() method。

  singleTask

  系统会创建一个新task(如果没有启动应用)和一个activity新实例在新task根部,然后,如果activity实例已经存在单独的task中,系统会调用已经存在activity的 onNewIntent()方法,而不是存在新实例,仅有一个activity实例同时存在。

<activity android:name=".activity.ActivityA" android:label="ActivityA" android:launchMode="standard">
  <intent-filter>
     <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>
<activity android:name=".activity.ActivityB" android:label="ActivityB" android:launchMode="singleTask">
  <intent-filter>
     <action android:name="android.intent.action.MAIN" />
    </intent-filter>
</activity>
<activity android:name=".activity.ActivityC" android:label="ActivityC" android:launchMode="standard">
  <intent-filter>
     <action android:name="android.intent.action.MAIN" />
    </intent-filter>
</activity>

 操作1:ActivityA->ActivityB->ActivityC->ActivityA->ActivityB->ActivityC

  

   可以看到,当再次进入ActivityB时,没有onCreate,而是onNewIntent(绿55)。

   这里我们也可以发现一个现象,当在调用到ActivityB的onNewIntent时,之前的ActivityA和ActivityC都调用了onDestory。也就是说,系统发现栈中存在ActivityB的实例时,ActivityA和ActivityB都弹栈了。

   列出Log日志(这里设ActivityA的LaunchMode为singleTask),ActivityB和ActivityC都在onNewIntent前后调用了onDestory。

  

  singleInstance

    和singleTask相似,除了系统不会让其他的activities运行在所有持有的task实例中,这个activity是独立的,并且task中的成员只有它,任何其他activities运行这个activity都将打开一个独立的task。

<activity android:name=".activity.ActivityA" android:launchMode="singleTask">
  <intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>
<activity android:name=".activity.ActivityB" android:launchMode="singleInstance">
  <intent-filter>
     <action android:name="android.intent.action.MAIN" />
  </intent-filter>
</activity>
<activity android:name=".activity.ActivityC">
  <intent-filter>
     <action android:name="android.intent.action.MAIN" />
   </intent-filter>
</activity>

 

 操作1:ActivityA->ActivityB->ActivityA

  

 

  可以发现,两个Activity是在不同的Task中,其次,当调用到onNewIntent时,ActivityB没有被Destory,互不干涉。

  操作2:ActivityA->ActivityB->ActivityC,按返回键

  

 

  图解:

  

  刚进入应用,创建TaskA,ActivityA为栈顶,从ActivityA到ActivityB,ActivityB进入TaskB(如果再次进入ActivityB,则不创建Task,调用onNewIntent),此时TaskB中的ActivityB为栈顶,从ActitivyB到ActivityC,ActivityC为栈顶。

  一直按返回键,先从TaskA中依次将Activity弹出,然后再从TaskB中将ActiviyB弹出。ActiviyC->ActivityA->ActivityB。

  这里分析一个问题,浏览器的LaunchMode为singleTask,所以如果当你点击一个连接下载文件时(由一个activity来处理下载,launchmode为standard),如果再次进入浏览器,那么下载页面就被Destory了,那么这里我们可以把下载页面LaunchMode设置为singleInstance可以解决这个问题。

  Affinity定义

  Affinity更像是表明了activity属于哪个task,默认情况下,应用所有的activities都有相同的affinity,所以都是在相同的task中。然后你可以编辑默认的affinity。Activities定义在不同的应用可以共享一个affinity,或者activities定义在相同的应用中可以被不同的affinities所关联。

  你可以编辑在<activity>元素中activity的taskAffinity属性。

   先看看两种不同的情况下affinity的表现:

  • 当运行一个activity包含了FLAG_ACTIVITY_NEW_TASK标记
//ActivityA.java
Intent intent = new Intent();    
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setClass(ActivityA.this, ActivityB.class); startActivity(intent);
<activity android:name=".activity.ActivityA" android:taskAffinity="com.android.demo.affinity1">
  <intent-filter>
     <action android:name="android.intent.action.MAIN" />
       <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity android:name=".activity.ActivityB" android:taskAffinity="com.android.demo.affinity2">
  <intent-filter>
     <action android:name="android.intent.action.MAIN" />
   </intent-filter>
</activity>

操作1:不同的affinity值,ActivityA->ActivityB

如果已经存在相同affinity,那么新activity运行在这个task中,否则,系统创建新task。

操作2:相同的affinity值,ActivityA->ActivityB

<activity android:name=".activity.ActivityA" android:taskAffinity="com.android.demo.affinity1">
  <intent-filter>
     <action android:name="android.intent.action.MAIN" />
       <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity android:name=".activity.ActivityB" android:taskAffinity="com.android.demo.affinity2">
  <intent-filter>
     <action android:name="android.intent.action.MAIN" />
   </intent-filter>
</activity>

可以看出ActivityA和ActivityB都运行在同一个task中。

 

  • 当Activity的allowTaskReparenting的属性设为'true'

  使用来表示是否允许activity重新附属其他Task,还是举例说明吧。

  有两个应用,Demo1和Demo2,Demo1中有2个Activity(ActivityA,ActivityC),ActivityA可以转向到ActivityC,Demo2中有一个Activity(ActivityB),也可以转向到ActivityC。

  操作1:设置ActivityC的allowTaskReparenting属性为true。

      运行Demo2,转向到ActivityC,在ActivityC中打印信息,返回到HOME界面,运行Demo1。

//Demo1 
//ActivityA.java
Intent intent = new Intent();
intent.setClass(ActivityA.this, ActivityC.class);
startActivity(intent);

//ActivityC.java
tv.setText(ActivityC.this.toString());

//Demo2
//ActivityB.java
Intent intent = new Intent();
intent.setClassName("com.android.demo","com.android.demo.activity.ActivityC");
ActivityB.this.startActivity(intent);
//Demo1
<activity android:name=".activity.ActivityA">
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>
<activity android:name=".activity.ActivityC" android:allowTaskReparenting="true">
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
  </intent-filter>
</activity>

//Demo2 <activity android:name=".ActivityB">   <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>

 运行结果:(黄色Demo1,绿色Demo2)

  

    ActivityB转向到ActivityC,此时ActivityC就关联到Demo2的Task中,TaskID都为231。在运行Demo1时,看到是ActivityC而不是ActivityA。当再次进入Demo2时就看不到ActivityC了。

  操作2:将ActivityC的taskAffinity设置为"com.android.demo.activityc"。

      运行Demo2,转向到ActivityC,在ActivityC中打印信息,返回到HOME界面,运行Demo1。

//Demo1
<activity android:name=".activity.ActivityC"
            android:taskAffinity="com.android.demo.activityc"
            android:allowTaskReparenting="true">
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
  </intent-filter>
</activity>

 运行结果:

  

   从结果中可以看出,Demo1和Demo2都拥有ActivityC,也就是说有2个Task里存在ActivityC,分别被Demo1和Demo2所使用。

  操作3:将ActivityC和ActivityB的taskAffinity都设为"com.android.demo.activityc"。

      运行Demo2,转向到ActivityC,在ActivityC中打印信息,返回到HOME界面,运行Demo1。

//Demo2
<activity android:name=".ActivityB" android:taskAffinity="com.android.demo.activityc">
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>

//Demo1
<activity android:name=".activity.ActivityC"
            android:taskAffinity="com.android.demo.activityc"
            android:allowTaskReparenting="true">
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
  </intent-filter>
</activity>

  运行结果:

  

   和操作1相反,再进入Demo2时看到是ActivityC,进入Demo1都是看到ActivityA。

 

  写到最后越来越崩溃了,如果有什么地方写的不对或不清楚请指明。


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android程序设计之AIDL实例详解 iis7站长之家
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3