当前位置:  编程技术>移动开发
本页文章导读:
    ▪ScrollView上,ListView生存之道        ScrollView下,ListView生存之道首先讲一下我遇到的需求吧,页面是这样的,上边有东西,中间是列表,下边还有东西。首先我看到列表立刻就想到了用ListView,但是页面有限,只能用ScrollView包.........
    ▪ Object-C中nil, NULL跟NSNull        Object-C中nil, NULL和NSNull控制处理不当是引起程序错误乃至崩溃的重要原因之一。 因为Object-C的集合对象,如NSArray、NSDictionary、NSSet等,都有可能包含NSNull对象,所以,如果一下代码中的item为N.........
    ▪ Java背后的秘密之怎么开发出高性能Java程序05       Java背后的秘密之如何开发出高性能Java程序051、开发高性能Java程序的原则和方法: 决定一个Java程序性能的好坏,是多方面的因素,包括前期的系统结构设计、底层平台架构设计、应用开发中.........

[1]ScrollView上,ListView生存之道
    来源: 互联网  发布时间: 2014-02-18
ScrollView下,ListView生存之道

首先讲一下我遇到的需求吧,页面是这样的,上边有东西,中间是列表,下边还有东西。首先我看到列表立刻就想到了用ListView,但是页面有限,只能用ScrollView包一下。想到就做呗。我就在ScrollView里面加了一个ListView, ListView设置的是wapcontent,这样就出现了ListView数据只显示出了一行。好的,解决问题的方案就来了。

一.设置scrollView中的ListView内容全部显示,不能滑动,将滑动交给scrollView去做。

做法:在设置adapter之前,重新计算ListView的高度,我这里写了一个方法:

/**
	 * 动态设置listView的高度
	 * count 总条目
	 */
	private void setListViewHeight(ListView listView, BaseAdapter adapter,
			int count) {
		int totalHeight = 0;
		for (int i = 0; i < count; i++) {
			View listItem = adapter.getView(i, null, listView);
			listItem.measure(0, 0);
			totalHeight += listItem.getMeasuredHeight();
		}

		ViewGroup.LayoutParams params = listView.getLayoutParams();
		params.height = totalHeight + (listView.getDividerHeight() * count);
		listView.setLayoutParams(params);
	}

这样做的前提条件是布局文件中ListView的高度要指定,这样才能重新计算,不要设成wapcontent!

二.不全部展示数据,二者皆可滑动。

此方法不用重新计算ListView的高度,只需焦点在Listview上的时候,ScrollView能把滑动权主动交给Listview,这样需要重写ScrollView的一个方法,如下:

@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		return false;
	}

这样Scrollview就会根据焦点而让出滑动事件。

三.  不重新计算ListView的高度,展示所有数据,ListView不可滑动。

这个做法是重写ListView的onMeasure方法,如下:

/**
	 * 设置不滚动
	 */
	public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
	{
		int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
				MeasureSpec.AT_MOST);
		super.onMeasure(widthMeasureSpec, expandSpec);

	}
这种方法是同事告诉我的,我没有用过。

做到这里,ScrollView和ListView的问题是解决了,但是ListView的效率问题出现了。

你会发现在ListView的adapter里的getview方法重复执行了很多次,技术使用了缓存技术也是无用的。

有时候数据只有两三个,但是getView方法却被执行了40多次。这样肯定是不行的。但是为什么单独使用ListView的时候却不会出现这种问题呢?

这个原因肯定出在ScrollView和ListView共存上。Google了一下,外国人都不建议他们共存,但是需求是这样的怎么办呢?

我的最终:自己写一个类似ListView的东西

一. 最初:

/**
 * 虚拟listview
 * 
 * @author JustMe
 * 
 */
public class MyListView extends LinearLayout {
	
	private BaseAdapter adapter;
	private MyOnItemClickListener onItemClickListener;

	/**
	 * 通知更新listview
	 */
	public void notifyChange() {
		int count = getChildCount();
		LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT,
				LayoutParams.WRAP_CONTENT);
		for (int i = count; i < adapter.getCount(); i++) {
			final int index = i;
			final LinearLayout layout = new LinearLayout(getContext());
			layout.setLayoutParams(params);
			layout.setOrientation(VERTICAL);
			View v = adapter.getView(i, null, null);
			v.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					if (onItemClickListener != null) {
						onItemClickListener.onItemClick(MyListView.this,
								layout, index, adapter.getItem(index));
					}
				}
			});
			// 每个条目下面的线
			ImageView imageView = new ImageView(getContext());
			imageView.setBackgroundResource(R.drawable.divider_list);
			imageView.setLayoutParams(params);
			layout.addView(v);
			layout.addView(imageView);
			addView(layout, index);
		}
	}

	public MyListView(Context context) {
		super(context);
		initAttr(null);
	}

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

	/**
	 * 设置方向
	 * 
	 * @param attrs
	 */
	public void initAttr(AttributeSet attrs) {
		setOrientation(VERTICAL);
	}

	


	public BaseAdapter getAdapter() {
		return adapter;
	}

	/**
	 * 设置adapter并模拟listview添加数据
	 * 
	 * @param adpater
	 */
	public void setAdapter(BaseAdapter adpater) {
		this.adapter = adpater;


		notifyChange();

	}

	/**
	 * 设置条目监听事件
	 * 
	 * @param onClickListener
	 */
	public void setOnItemClickListener(MyOnItemClickListener onClickListener) {
		this.onItemClickListener = onClickListener;
	}



	/**
	 * 点击事件监听
	 * 
	 * @author JustMe
	 * 
	 */
	public static interface MyOnItemClickListener {
		public void onItemClick(ViewGroup parent, View view, int position,
				Object o);

	}
}
这样实现了ListView的最基本的功能,并且提高了效率,例如,全选功能比以上那些方法的速度提高了2-3秒,页面也不卡顿。

缺点是不能一次加载很多的数据,不然数据会显示的很慢,最好分页加载。说到分页,之前都是在ListView上加footerView,在这里也可以做到。

二. 升级:

public class MyListView  extends LinearLayout{
	private BaseAdapter adapter;
	private MyOnItemClickListener onItemClickListener;
	boolean footerViewAttached = false;
	private View footerview;

	/**
	 * 通知更新listview
	 */
	public void notifyChange() {
		int count = getChildCount();
		if (footerViewAttached) {
			count--;
		}
		LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
		for (int i = count; i < adapter.getCount(); i++) {
			final int index = i;
			final LinearLayout layout = new LinearLayout(getContext());
			layout.setLayoutParams(params);
			layout.setOrientation(VERTICAL);
			View v = adapter.getView(i, null, null);
			v.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					if (onItemClickListener != null) {
						onItemClickListener.onItemClick(MyListView.this, layout, index,
								adapter.getItem(index));
					}
				}
			});
			ImageView imageView = new ImageView(getContext());
			imageView.setBackgroundResource(R.drawable.divider_list);
			imageView.setLayoutParams(params);
			layout.addView(v);
			layout.addView(imageView);
			addView(layout, index);
		}
	}

	public MyListView(Context context) {
		super(context);
		initAttr(null);
	}

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

	public void initAttr(AttributeSet attrs) {

		setOrientation(VERTICAL);
	}

	/**
	 * 初始化footerview
	 * 
	 * @param footerView
	 */
	public void initFooterView(final View footerView) {
		this.footerview = footerView;
	}

	/**
	 * 设置footerView监听事件
	 * 
	 * @param onClickListener
	 */
	public void setFooterViewListener(OnClickListener onClickListener) {
		this.footerview.setOnClickListener(onClickListener);
	}

	public BaseAdapter getAdapter() {
		return adapter;
	}

	/**
	 * 设置adapter并模拟listview添加�?��数据
	 * 
	 * @param adpater
	 */
	public void setAdapter(BaseAdapter adpater) {
		this.adapter = adpater;

		removeAllViews();
		if (footerViewAttached)
			addView(footerview);

		notifyChange();

	}

	/**
	 * 设置条目监听事件
	 * 
	 * @param onClickListener
	 */
	public void setOnItemClickListener(MyOnItemClickListener onClickListener) {
		this.onItemClickListener = onClickListener;
	}

	/**
	 * 没有下一页了
	 */
	public void noMorePages() {
		if (footerview != null && footerViewAttached) {
			removeView(footerview);
			footerViewAttached = false;
		}
	}

	/**
	 * 可能还有下一�?
	 */
	public void mayHaveMorePages() {
		if (!footerViewAttached && footerview != null) {
			addView(footerview);
			footerViewAttached = true;
		}
	}

	public static interface MyOnItemClickListener {
		public void onItemClick(ViewGroup parent, View view, int position, Object o);

	}
}

这样就可以添加footerView了。最终我是使用了这种方案。






1楼woshicuihu3天前 10:15牛逼 牛逼 牛逼 牛逼 牛逼 牛逼 牛逼 牛逼 牛逼 牛逼 牛逼 牛逼 牛逼 牛逼 牛逼 牛逼 牛逼

    
[2] Object-C中nil, NULL跟NSNull
    来源: 互联网  发布时间: 2014-02-18
Object-C中nil, NULL和NSNull

控制处理不当是引起程序错误乃至崩溃的重要原因之一。

因为Object-C的集合对象,如NSArray、NSDictionary、NSSet等,都有可能包含NSNull对象,所以,如果一下代码中的item为NSNull,则会引起程序崩溃。

NSString *item=[NSArray objectAtIndex:i];
if([item isEqualToString:@"TestNumber"])
{
    //
}

以下代码是常见的错误,release对象没有设置为nil,从而引起程序崩溃。
id someObject=[[Object alloc] init];
//...
[someObject release];
//...
if(someObject)
{
    //crash here
}

nil用来给对象赋值(Object-C的任何对象都属于id类型),NULL则给任何指针赋值,NULL和nil不能互换,nil用于类指针赋值(在Object-C中类是一个对象,是类的meta-class的实例),而NSNull则用于集合操作,虽然它们表示的都是空值,但是使用场合完全不同,所以在编码时严格按照变量类型来赋值,将正确的空值赋给正确的类型,使代码易于阅读和维护,也不易引起错误。

//判断对象不空
if(object) {}

//判断对象为空
if(object == nil) {}

//数组初始化,空值结束
NSArray *pageNames=[[NSArray alloc] initWithObjects:@"DocumentList",@"AdvancedSearch",@"Statistics",nil];

//判断数组元素是否为空
UIViewController *controller=[NSArray objectAtIndex:i];
if((NSNull *)controller == [NSNull null])
{
    //
}

//判断字典对象的元素是否为空
NSString *userId=[NSDictionary objectForKey:@"UserId"];
if(userId == [NSNull null])
{
    //
}

Object-C有个可爱的特性,就是当发消息给nil对象时,系统返回0值而不是引起异常,这和JAVA烦人的NullPointerException以及C/C++的程序直接崩溃的处理完全不一样,明白Object-C的这个特性对于开发正确的IOS程序非常重要,因为nil是对象的合法值,nil对象同样可以接收消息,例如:

person=nil;
[person castBallot];
NSLog("person=%@",person);

对象置空,然后发送消息,程序同样接着往下执行而不会崩溃。



    
[3] Java背后的秘密之怎么开发出高性能Java程序05
    来源: 互联网  发布时间: 2014-02-18
Java背后的秘密之如何开发出高性能Java程序05

1、开发高性能Java程序的原则和方法:
决定一个Java程序性能的好坏,是多方面的因素,包括前期的系统结构设计、底层平台架构设计、应用开发中的代码编写以及技巧的使用,系统平台的软件配置,系统平台的硬件性能等等。这里只给出代码编写方面的一些原则和方法。

相对于Java的其他方面,在性能领域Java饱受的非议可能最多。许多人认为,Java如果想更好的发展下去必须解决性能问题。然而真正的事实是Java在编译器、JVM以及运行期优化方面确实在不断的进步,Java正在运行的越来越快。实际上很多的性能问题,是由于设计不佳引起的,与Java本身并无关系。在拙劣的设计和编码面前,无论你使用多少运行期优化,无论你的编译技术多么先进,无论你的硬件平台性能多么强大,最后的代码运行依然低效。

同样无论运行期优化技术、编译技术以及硬件平台多么强大,运用一些已被验证对Java运行性能有益的技术,总是能获得非常好的收益。

优化程序代码的注意事项:
1.除非必须优化,否则不要轻易改动;
2.改动之后要进行仔细的测试;
3.在各个JVM产品中,优化的方式是有区别的;

2、高性能Java的编码原则:
(1)、先把焦点放在设计、数据结构和算法身上;
(2)、不要依赖于编译器编译期优化技术,正确理解运行期代码优化技术以及正确使用运行期代码优化;
(3)、使用StringBuffer类完成字符串连接;
(4)、将对象创建成本降至最低,即尽量创建轻量级对象;
                1、合理设计对象大小
                2、合理设计类的继承深度
                3、类的构造函数要短小精干
                4、不要创建非必要的对象
                5、将对象的创建拖延到最后一刻,即延迟加载技术
                6、可能的话要自己实现一个对象缓冲管理池,将对象的创建与回收控制在一个合理的范围内
(5)、降低同步化带来的影响;
                1、合理识别是否一定要使用同步控制,尽量从设计上避免
                2、注意控制同步代码范围,避免对线程活跃度造成影响
                3、合理使用锁变量,做到线程分离,提高程序并发度,更进一步提高程序吞吐量
                4、用于锁变量的对象不宜过多,当要使用多个对象作为锁变量时,一定要确保在代码中自始自终按照同样的顺序锁定它们,否则可能导致死锁
(6)、尽可能使用Stack变量和基本类型完成必要的任务;
(7)、使用static、final、private方法以促成inlining;
(8)、实例变量初始化一次就好;(即一定义就会有一个初始值,下面不需要再进行一次初始化)
(9)、集群类对象的处理;
                1、如何正确遍历集群类?
                2、如何复制数组元素?
                3、如何正确选择使用合适的集群类?
(10)、尽可能重用对象;
(11)、使用延迟加载技术;

当然上面都是理论方法,实践需要靠大家自己去了,两个代码实在不知道那种性能更好,javap看字节码执行,看步骤,这是最土的方法,却是最能说服自己的证据!


本文出自 “火 山 哥” 的博客,未经授权,谢绝转载!


    
最新技术文章:
▪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提高之手游转电视游戏的模拟操控
 


站内导航:


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

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

浙ICP备11055608号-3