1.sortedArrayUsingSelector
NSMutableArray *array = [NSMutableArray arrayWithObjects: [NSDictionary dictionaryWithObjectsAndKeys:@"Obj0", [NSNumber numberWithInt:0], nil], [NSDictionary dictionaryWithObjectsAndKeys:@"Obj5", [NSNumber numberWithInt:5], nil], [NSDictionary dictionaryWithObjectsAndKeys:@"Obj2", [NSNumber numberWithInt:2], nil], [NSDictionary dictionaryWithObjectsAndKeys:@"Obj3", [NSNumber numberWithInt:3], nil], [NSDictionary dictionaryWithObjectsAndKeys:@"Obj1", [NSNumber numberWithInt:1], nil], [NSDictionary dictionaryWithObjectsAndKeys:@"Obj4", [NSNumber numberWithInt:4], nil], nil]; NSArray *resultArray = [array sortedArrayUsingSelector:@selector(compare:)];
因为NSDictionary没有compare的排序比较方法,所以需要我们自己写
.h @interface NSDictionary (compare) {} -(NSComparisonResult)compare:(NSDictionary *)otherDictionary; @end .m @implementation NSDictionary (compare) - (NSComparisonResult)compare: (NSDictionary *)otherDictionary { NSDictionary *tempDictionary = (NSDictionary *)self; NSNumber *number1 = [[tempDictionary allKeys] objectAtIndex:0]; NSNumber *number2 = [[otherDictionary allKeys] objectAtIndex:0]; NSComparisonResult result = [number1 compare:number2]; return result == NSOrderedDescending; // 升序 // return result == NSOrderedAscending; // 降序 } @end
2.sortedArrayUsingComparator
NSMutableArray *array = [NSMutableArray arrayWithObjects: [NSDictionary dictionaryWithObjectsAndKeys:@"Obj0", [NSNumber numberWithInt:0], nil], [NSDictionary dictionaryWithObjectsAndKeys:@"Obj5", [NSNumber numberWithInt:5], nil], [NSDictionary dictionaryWithObjectsAndKeys:@"Obj2", [NSNumber numberWithInt:2], nil], [NSDictionary dictionaryWithObjectsAndKeys:@"Obj3", [NSNumber numberWithInt:3], nil], [NSDictionary dictionaryWithObjectsAndKeys:@"Obj1", [NSNumber numberWithInt:1], nil], [NSDictionary dictionaryWithObjectsAndKeys:@"Obj4", [NSNumber numberWithInt:4], nil], nil]; // NSArray *resultArray = [array sortedArrayUsingSelector:@selector(compare:)]; NSArray *resultArray = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { NSNumber *number1 = [[obj1 allKeys] objectAtIndex:0]; NSNumber *number2 = [[obj2 allKeys] objectAtIndex:0]; NSComparisonResult result = [number1 compare:number2]; return result == NSOrderedDescending; // 升序 // return result == NSOrderedAscending; // 降序 }];3.sortedArrayUsingDescriptors & sortUsingDescriptors
.h @interface Person : NSObject { NSString *_name; NSInteger _age; } @property (nonatomic, retain) NSString *name; @property (nonatomic, assign) NSInteger age; @end .m @implementation Person @synthesize name = _name; @synthesize age = _age; - (void)dealloc { [_name release]; [super dealloc]; } @end
Person *person1 = [[Person alloc] init]; [person1 setName:@"ABC"]; [person1 setAge:24]; Person *person2 = [[Person alloc] init]; [person2 setName:@"ACB"]; [person2 setAge:22]; Person *person3 = [[Person alloc] init]; [person3 setName:@"ABD"]; [person3 setAge:33]; NSMutableArray *array = [NSMutableArray arrayWithObjects:person1, person2, person3, nil]; [person1 release]; [person2 release]; [person3 release]; NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"_age" ascending:YES]; NSArray *tempArray = [array sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]]; for(NSInteger i = 0; i < [tempArray count]; i++) { NSLog(@"%@--------%d\n", [[tempArray objectAtIndex:i] name], [[tempArray objectAtIndex:i] age]); } // [array sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]]; // // for(NSInteger i = 0; i < [array count]; i++) // { // NSLog(@"%@--------%d\n", [[array objectAtIndex:i] name], [[array objectAtIndex:i] age]); // }
sortDescriptorWithKey:@"_age",以age作为标准来做比较。
Person *person1 = [[Person alloc] init]; [person1 setName:@"ABCD"]; [person1 setAge:24]; Person *person2 = [[Person alloc] init]; [person2 setName:@"ACBD"]; [person2 setAge:22]; Person *person3 = [[Person alloc] init]; [person3 setName:@"ABDC"]; [person3 setAge:33]; Person *person4 = [[Person alloc] init]; [person4 setName:@"ACDB"]; [person4 setAge:22]; NSMutableArray *array = [NSMutableArray arrayWithObjects:person1, person3, person4, person2, nil]; [person1 release]; [person2 release]; [person3 release]; [person4 release]; NSSortDescriptor *sortDescriptor1 = [NSSortDescriptor sortDescriptorWithKey:@"_age" ascending:YES]; NSSortDescriptor *sortDescriptor2 = [NSSortDescriptor sortDescriptorWithKey:@"_name" ascending:YES]; NSArray *tempArray = [array sortedArrayUsingDescriptors:[NSArray arrayWithObjects:sortDescriptor1, sortDescriptor2, nil]]; for(NSInteger i = 0; i < [tempArray count]; i++) { NSLog(@"%@--------%d\n", [[tempArray objectAtIndex:i] name], [[tempArray objectAtIndex:i] age]); } // [array sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]]; // // for(NSInteger i = 0; i < [array count]; i++) // { // NSLog(@"%@--------%d\n", [[array objectAtIndex:i] name], [[array objectAtIndex:i] age]); // }
NSSortDescriptor *sortDescriptor1 = [NSSortDescriptor sortDescriptorWithKey:@"_age" ascending:YES];
NSSortDescriptor *sortDescriptor2 = [NSSortDescriptor sortDescriptorWithKey:@"_name" ascending:YES];
NSArray *tempArray = [array sortedArrayUsingDescriptors:[NSArray arrayWithObjects:sortDescriptor1, sortDescriptor2, nil]];
这里的NSArray中的第一元素表示首先按照这个元素的升序或者降序进行排序,对于有重复项的,再按照第二元素进行排序,依次进行类推
关于ListView中的适配器Adapter的设置方法有很多种。可以使用SimpleAdapter实现简单的列表各项,当然我们一般使用比较多的是定义一个Adapter继承BaseAdapter实现的....
当然其他方法也有,但是本人目前只使用过这两个方法,当然也是比较常用的方法.
1、
SimpleAdapter adapter=new SimpleAdapter(this,list,R.layout.musiclist_item,new String[]{"title","artiest","dur_time","img"},
new int[]{ R.id.music,R.id.singer,R.id.time,R.id.img});
listview.setAdapter(adapter);
实例化SimpleAdapte过程中,第二个参数是列表中显示各项内容的一个List,第三项是列表项的Layout,第四个参数和第五个参数分别对应第二个参数和第三个参数里面各项的映射关系...如我们可以定义list为:List<Map<String, Object>> list =new ArrayList<Map<String, Object>>(); Map中的String键值参数需要与SimpleAdapter构造函数中的第四个参数里面参数对应,呵呵,可能说的不是很清楚..自己做个demo就能很好的实现所说的该功能...
2、使用BaseAdapter
BaseAdapter是实现了ListAdapter和SpinnerAdapter两个接口,当然它也可以直接给ListView和Spinner等UI组件直接提供数据。
自定义BaseAdapter子类,就需要实现下面几个方法,
public int getCount() {
}
public Object getItem(int position) {
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
}
第一个getCount()方法主要实现的是返回列表的行数,getItem()是指返回的Object值,而getItemId()方法则是返回列表中各项的id值,一般用于对列表进行单击监听处理时使用,比如对列表中最后的(更多)项进行监听处理时可以通过在getItemId中返回一个-1值进行确认选中该项。
getView()方法是最重要的方法,它是将获取数据后的View组件返回,如ListView中每一行里的TextView、Gallery中的每个ImageView等组件。通过该方法调用从而得到列表中的所有行项。
我们使用一个继承BaseAdapter的自定义适配器通常要和一个存储列表每项数据信息的List<?>对象进行搭配使用...
好了,闲话不说,上点代码..
class CommentAdapter extends BaseAdapter{ private View rowView; private Map<Integer, View> rowViews = new HashMap<Integer, View>(); public CommentAdapter(){ } @Override public int getCount() { // TODO Auto-generated method stub return comment_list.size()+1; } @Override public Object getItem(int position) { // TODO Auto-generated method stub return comment_list.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub if(this.getCount()-1==position) return -1; else return position; } @Override public View getView(int position, View view, ViewGroup arg2) { // TODO Auto-generated method stub if(position==this.getCount()-1){ view=LayoutInflater.from(Comment.this).inflate(R.layout.more_item, null); TextView more_item=(TextView)view.findViewById(R.id.more_item); if((this.getCount()-1)%PageSize!=0) more_item.setText("没有留言了哦..."); return view; } else{ LayoutInflater layoutInflater = LayoutInflater.from(Comment.this);//从当前上下文得到LayoutInflater rowView = rowViews.get(position);//用了一个类似缓存功能,不过据说List中就有缓存功能.... if(rowView==null){ rowView=layoutInflater.inflate(R.layout.comment_item, null); TextView comment_name = (TextView) rowView.findViewById(R.id.comment_item_name); TextView comment_time = (TextView) rowView.findViewById(R.id.comment_item_time); TextView comment_text = (TextView) rowView.findViewById(R.id.comment_item_text); comment_name.setText(comment_list.get(position).getName()); comment_time.setText(getTime(comment_list.get(position).getTime())); comment_text.setText(comment_list.get(position).getText()); rowViews.put(position, rowView); } return rowView; } }这样自定义的Adapter就完成了。
然后在对应的列表中使用setAdapter(adapter)即可。
CommentAdapter adapter=new CommentAdapter();
comment_listview.setAdapter(adapter);
3.在列表中添加最后一项(更多),当我们点击它的时候就会加载出更多的列表项..
此方法实现不是很难,只要在自定义的Adapter中的getCount()中return值加1,同时在getItemId(position)方法中处理一下。如下
public int getCount() { // TODO Auto-generated method stub return comment_list.size()+1; } public long getItemId(int position) { // TODO Auto-generated method stub if(this.getCount()-1==position) return -1; else return position; }
这样,当列表到最好一项(更多)的时候,返回ID变为-1,方便之后的单击监听处理。
同样,getView()方法也要处理
public View getView(int position, View view, ViewGroup arg2) { // TODO Auto-generated method stub if(position==this.getCount()-1){ view=LayoutInflater.from(Comment.this).inflate(R.layout.more_item, null); TextView more_item=(TextView)view.findViewById(R.id.more_item); if((this.getCount()-1)%PageSize!=0) more_item.setText("没有留言了哦..."); return view; } else{ ... } }
通过此方法返回一个表明(更多)的列表选项。
这样自定义Adapter就处理好了。接下来实现单击监听...
comment_listview.setOnItemClickListener(new OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3) { // TODO Auto-generated method stub if(arg3==-1){//通过此判断为最后一个列表项 page++; comment_list.addAll(getComment(page));//添加更多的列表内容,加载 ((CommentAdapter)comment_listview.getAdapter()).notifyDataSetChanged();//更新列表... } } });
当选中列表最后一项时候,
page++;
comment_list.addAll(getComment(page));
((CommentAdapter)comment_listview.getAdapter()).notifyDataSetChanged();//更新列表...
从而实现对列表信息进行"更多"加载....
现在上一张自己做的一个新浪微博的评论列表
本文通过FrameLayout和LinearLayout来布局,并通过捕捉onTouchEvent事件来实现画面的随意移动,并同时显示移动后画面坐标。
1、先上布局文件:main.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:id="@+id/container" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"> <ImageView android:src="/blog_article/@drawable/icon1/index.html" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <LinearLayout android:id="@+id/showXY" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5px" android:text="当前坐标:"/> <TextView android:id="@+id/xyValue" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5px" android:text="0,0"/> </LinearLayout> </FrameLayout>
2、Activity代码,MainActivity.java:
package org.shuxiang.test; import android.app.Activity; import android.os.Bundle; import android.view.MotionEvent; import android.view.Window; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends Activity { private LinearLayout container; private int currentX; private int currentY; private TextView xyValue; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.main); container = (LinearLayout) findViewById(R.id.container); xyValue = (TextView) findViewById(R.id.xyValue); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { currentX = (int) event.getRawX(); currentY = (int) event.getRawY(); break; } case MotionEvent.ACTION_MOVE: { int x2 = (int) event.getRawX(); int y2 = (int) event.getRawY(); container.scrollBy(currentX - x2 , currentY - y2); currentX = x2; currentY = y2; xyValue.setText(x2 + "," + y2); break; } case MotionEvent.ACTION_UP: { break; } } return true; } }