最近在开发博聆网的网站客户端。博聆网是一个社区网站,里面有网友发的贴子,我的客户端初始只显示15条,在最底层有一个Button按钮,命名为更多,当用户点击更多按钮时,客户端会在原有基础上再加载15篇帖子。而在加载过程中该Button变为一个旋转进度条,防止在程序加载数据,界面假死的时候再次点击导致程序关闭。而当数据接收好后,进度条会再次变回button。
来看一下效果:
初始状态:
点击效果:
点击后显示更多15条:
好了,我先说一下它的大致实现思路:
1.先在界面上定义了一个Button和一个ProgressBar,ProgressBar初始设为隐藏。
2.将这两个控件放到一个布局中,然后将布局添加到list的末尾。
3.定义两个广播,一个用于通知button变为ProgressBar,另一个用于在数据加载完毕后将进度条变为Button。
4.给Button设置消息响应函数,这里会用到刚才定义的广播。
代码(注:由于完整源码还有很多别的操作,这里我只贴出跟次button有效的代码段):
定义Button和ProgressBar,还有两个广播事件ButtonBroadCast和BackBroadcast的对象,以及一些布局参数:
private Button more=null; private ProgressBar bar =null; private ButtonBroadcast buttonchange=null; private BackBroadcast buttonback=null;
private LayoutParams FFlayoutParams =new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT); private LayoutParams mLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT); private LayoutParams BLayoutParams =new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
在onCreate()中:
more=new Button(this); more.setText("更多"); more.setGravity(Gravity.CENTER); bar=new ProgressBar(this); bar.setVisibility(View.GONE); bar.setMax(5); bar.setMinimumHeight(5); bar.setMinimumWidth(5); lin.addView(more,FFlayoutParams); lin.addView(bar, BLayoutParams); lin.setGravity(Gravity.CENTER); LinearLayout loadingLayout = new LinearLayout(this); loadingLayout.addView(lin,mLayoutParams); loadingLayout.setGravity(Gravity.CENTER); hotlist=(ListView)findViewById(R.id.list); hotlist.addFooterView(loadingLayout);
注意:这里的Button和ProgressBar不在main.xml当中定义,而是在java代码中生成的,原因在于ListView这个控件的特殊性,listview一旦存在于一个布局文件当中,那么它就会覆盖整个屏幕,别的控件定义了也没法显示,这个大家可以试试只在listview中添加一条数据,再在它下面定义其他控件,看看那些控件显不显示。第二点,如果用RelativeLayout去布局,button是可以放在listview之下,但是,它是不随着list的拖动而移动的,也就是说,不管list如何,在总是在最下面,这与我们的设计不符。所以,我采用了list的addFooterView()方法,这样,button就存在与list的最后一个。代码中hotlist即是界面list对象。
下面是两个广播处理的代码:
private class ButtonBroadcast extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub String action=intent.getAction(); if(action.equals(ButtonAction)) { more.setVisibility(View.GONE); bar.setVisibility(View.VISIBLE); } } } private class BackBroadcast extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub String action=intent.getAction(); if(action.equals(BarAction)) { bar.setVisibility(View.GONE); more.setVisibility(View.VISIBLE); } } }
如果广播的动作是Buttonaction的话,button消失,bar显现,如果动作为BarAction,则相反。
下面是button的点击事件:
more.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub buttonchange=new ButtonBroadcast(); buttonback=new BackBroadcast(); filter1=new IntentFilter(); filter2=new IntentFilter(); filter1.addAction(ButtonAction); filter2.addAction(BarAction); intent1=new Intent(); intent2=new Intent(); intent1.setAction(ButtonAction); intent2.setAction(BarAction); new Thread(new Runnable() { public void run() { showmore(); handler.post(new Runnable() { public void run() { listadapter.notifyDataSetChanged(); HTTPRequestActivity.this.registerReceiver(buttonback, filter2); HTTPRequestActivity.this.sendBroadcast(intent2); HTTPRequestActivity.this.unregisterReceiver(buttonback); } }); } }).start(); HTTPRequestActivity.this.registerReceiver(buttonchange, filter1); HTTPRequestActivity.this.sendBroadcast(intent1); HTTPRequestActivity.this.unregisterReceiver(buttonchange); } } );
在函数中定义了两个IntentFilter类对象,用于过滤两种不同的action。并同时定义两个intent对象用于传递动作。showmore()函数调用后数据已载入本地,我们不用去管这个函数的实现,并用handler的post方法去让界面更新,并且发送让button消失的广播,等这些都执行完了,再发送调回button的广播。这里用到了一个新的线程是因为下载数据若是跟界面变化在一个线程当中,button效果也不会显现,因为线程阻塞的缘故。
在代码中的ButtonAction和BarAction定义如下:
private static final String ButtonAction="com.suns.HTTPRequestActivity.BUTTONCHANGE"; private static final String BarAction="com.suns.HTTPRequestActivity.BARCHANGE";
这里我们自定义两个action供intentfliter筛选,一般的命名方法为包名+“.”+aciton名。
好了到这里我们所要实现的功能点击Button变进度条,程序加载完毕后变回的效果就实现了,谢谢您的观看~
ps:给大家推荐这个不错的网站,博聆网。
里面帖子内容丰富很有意思,网友素质也挺高,是个比较有人情味的社区,建议大家去看看。
博聆网网址:www.bling0.com