410 likes | 418 Views
Display latest posts from followed users, central for user interactions. Features refresh and content navigation. XML layout file included for Android development.
E N D
功能描述: 呈现用户微博的首页信息,显示所有关注用户的最新微博,是各种操作的中心窗口。 点击刷新获取最新数据 点击更多内容获取下一页 左上角图标出现发表微博窗口 右上角为刷新窗口按钮 按下Menu出现内容 跳转流程: 可以跳转到各个子功能窗口,用户按下返回键弹出对话框提示用户是否退出。
Res/layout/maintab.xml <?xml version="1.0" encoding="UTF-8"?> <TabHost android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="0.0dip" android:layout_weight="1.0" /> <TabWidget android:id="@android:id/tabs" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="0.0" /> <RadioGroup android:gravity="center_vertical" android:layout_gravity="bottom" android:orientation="horizontal" android:id="@id/main_radio" android:background="@drawable/maintab_toolbar_bg" android:layout_width="fill_parent" android:layout_height="wrap_content"> <RadioButton android:id="@+id/radio_button0" android:tag="radio_button0" android:layout_marginTop="2.0dip" android:text="@string/main_home" android:drawableTop="@drawable/icon_1_n" style="@style/main_tab_bottom" /> <RadioButton android:id="@+id/radio_button1" android:tag="radio_button1" android:layout_marginTop="2.0dip" android:text="@string/main_news" android:drawableTop="@drawable/icon_2_n" style="@style/main_tab_bottom" /> <RadioButton android:id="@+id/radio_button2" android:tag="radio_button2" android:layout_marginTop="2.0dip" android:text="@string/main_my_info" android:drawableTop="@drawable/icon_3_n" style="@style/main_tab_bottom" /> <RadioButton android:id="@+id/radio_button3" android:tag="radio_button3" android:layout_marginTop="2.0dip" android:text="@string/menu_search" android:drawableTop="@drawable/icon_4_n" style="@style/main_tab_bottom" /> <RadioButton android:id="@+id/radio_button4" android:tag="radio_button4" android:layout_marginTop="2.0dip" android:text="@string/more" android:drawableTop="@drawable/icon_5_n" style="@style/main_tab_bottom" /> </RadioGroup> </LinearLayout> </TabHost>
编码添加页框内容 • mHost = this.getTabHost(); • mHost.addTab(mHost.newTabSpec(TAB_HOME).setIndicator(TAB_HOME) • .setContent(new Intent(MainActivity.this, HomeActivity.class))); • mHost.addTab(mHost.newTabSpec(TAB_MES).setIndicator(TAB_MES) • .setContent(new Intent(MainActivity.this, MsgActivity.class))); • mHost.addTab(mHost.newTabSpec(TAB_CONTACT).setIndicator(TAB_CONTACT) • .setContent(new Intent(MainActivity.this, MyContactActivity.class))); • mHost.addTab(mHost.newTabSpec(TAB_SEARCH).setIndicator(TAB_SEARCH) • .setContent(new Intent(MainActivity.this, SearchActivity.class))); • mHost.addTab(mHost.newTabSpec(TAB_MORE).setIndicator(TAB_MORE) • .setContent(new Intent(MainActivity.this, MoreActivity.class))); • mHost.addTab(mHost.newTabSpec(TAB_MAINAT).setIndicator(TAB_MAINAT) • .setContent(new Intent(MainActivity.this, MyContactAtActivity.class))); • mHost.addTab(mHost.newTabSpec(TAB_MESSAGE).setIndicator(TAB_MESSAGE) • .setContent(new Intent(MainActivity.this, MyContactMessageActivity.class)));
使用Radio实现Tab效果 • //信息标题获取 • msg_title = findViewById(R.id.msg_title); • main_at = (Button)msg_title.findViewById(R.id.bt_group_left); • main_comment = (Button)msg_title.findViewById(R.id.bt_group_middle); • main_message = (Button)msg_title.findViewById(R.id.bt_group_right); • main_at.setTag(MAIN_AT); • main_comment.setTag(MAIN_COMMENT); • main_message.setTag(MAIN_MESSAGE); • main_at.setOnClickListener(this); • main_comment.setOnClickListener(this); • main_message.setOnClickListener(this);
RadioGroup事件侦听改变Tab • radioderGroup = (RadioGroup) findViewById(R.id.main_radio); • radioderGroup.setOnCheckedChangeListener(this); • home = (RadioButton) findViewById(R.id.radio_button0); • home.setId(HOME); • mes = (RadioButton) findViewById(R.id.radio_button1); • mes.setId(MES); • my_contact = (RadioButton) findViewById(R.id.radio_button2); • my_contact.setId(MY_CONTACT); • search = (RadioButton) findViewById(R.id.radio_button3); • search.setId(SEARCH); • more = (RadioButton) findViewById(R.id.radio_button4); • more.setId(MORE); • //各Radio的事件 • publicvoid onCheckedChanged(RadioGroup group, int checkedId) { • msg_title.setVisibility(View.GONE);//把显示个人信息的TITLE隐藏 • switch(checkedId){ • case HOME: • mHost.setCurrentTabByTag(TAB_HOME); • break; • 。。。。。。。。..; • } • }
Top two Button 顶部处理 title_new_selected.png title_new_normal.png title_reload_selected.png title_reload_normal.png Drawable/titlenew.xml <?xml version="1.0" encoding="UTF-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_focused="true" android:drawable="@drawable/title_new_selected" /> <item android:state_selected="true" android:drawable="@drawable/title_new_selected" /> <item android:state_pressed="true" android:drawable="@drawable/title_new_selected" /> <item android:drawable="@drawable/title_new_normal" /> </selector> btnew.setBackgroundResource(R.drawable.title_button_newbolg); btrefresh.setBackgroundResource(R.drawable.title_button_refresh);
Menu的实现 图片资源: Menu图片资源 officialweibo.png menu_exit.png comment.png aboutweibo.png switchuser.png setting.png 35X35
Menu的实现home和info • public boolean onCreateOptionsMenu(Menu menu) { • // TODO Auto-generated method stub • menu.add(1, 1, 1, "").setIcon(R.drawable.menu_exit); • return super.onCreateOptionsMenu(menu); • } • @Override • public boolean onMenuItemSelected(int featureId, MenuItem item) { • // TODO Auto-generated method stub • switch(item.getItemId()) • { • case 1: • break; • } • return super.onMenuItemSelected(featureId, item); • }
让Menu能显示出来 • public boolean onKeyDown(int keyCode, KeyEvent event) { • // TODO Auto-generated method stub • if(keyCode==KeyEvent.KEYCODE_BACK) • { • MainService.promptExit(this); • return true; • } • return super.onKeyDown(keyCode, event); • }
上下文菜单 • registerForContextMenu(mAllStatusLV); • public boolean onContextItemSelected(MenuItem item) { • // TODO Auto-generated method stub • AdapterContextMenuInfo lm=(AdapterContextMenuInfo)item.getMenuInfo(); • Toast.makeText(this, ""+lm.id, 1000).show(); • return super.onContextItemSelected(item); • } • @Override • public void onCreateContextMenu(ContextMenu menu, View v, • ContextMenuInfo menuInfo) { • // TODO Auto-generated method stub • super.onCreateContextMenu(menu, v, menuInfo); • AdapterContextMenuInfo lm=(AdapterContextMenuInfo)menuInfo; • menu.setHeaderTitle("弹出菜单"); • menu.add(1, 1, 1, lm.id+"收藏"); • }
用户首页 home.xml • <?xml version="1.0" encoding="utf-8"?> • <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" • android:background="@color/white" android:orientation="vertical" • android:layout_width="fill_parent" android:layout_height="fill_parent"> • <include android:id="@+id/freelook_title" layout="@layout/title_two_button"/> • <include android:id="@+id/progress" layout="@layout/progress"/> • <ListView android:id="@+id/freelook_listview" android:divider="@drawable/divider_horizontal_timeline" android:dividerHeight="1.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content"/> • </LinearLayout>
自定义数据适配器 • private class ViewHolder{ • ImageView ivItemPortrait;//头像 有默认值 • TextView tvItemName;//昵称 • ImageView ivItemV;//新浪认证 默认gone • TextView tvItemDate;//时间 • ImageView ivItemPic;//时间图片 不用修改 • TextView tvItemContent;//内容 • ImageView contentPic;//自己增加的内容图片显示的imgView • View subLayout;//回复默认gone • TextView tvItemSubContent;//回复内容 subLayout显示才可以显示 • ImageView subContentPic;//自己增加的主要显示回复内容的图片。subLayout显示才可以显示 • }
刷新和更多 • public class WeiboStatuAdapter extends BaseAdapter{ • public Context con; • public List<Status> alls; • public LayoutInflater lif; • public WeiboStatuAdapter(Context con,List<Status> as) • {this.con=con; • lif=LayoutInflater.from(con); • this.alls=as; • } • public int getCount() {return alls.size()+2;} • public Object getItem(int arg0) {return null;} • public long getItemId(int index) { • if(index==0)//选中第一项 • { return 0; • }else if(index>0&&(index<this.getCount()-1)) • { return alls.get(index-1).getId();//如果用户选中了中间项 • }else{ • return -1;//表示用户选中最后一项 • }} • //增加更多的数据 • public void addMoreData(List<Status> moreStatus) • {this.alls.addAll(moreStatus);//把新数据增加到原有集合 • this.notifyDataSetChanged(); • }
listrefreshitem.xml • <?xml version="1.0" encoding="utf-8"?> • <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" • android:visibility="visible" android:gravity="center" • android:background="@color/white" android:orientation="horizontal" • android:layout_width="fill_parent" android:layout_height="90dip"> • <ProgressBar • android:id="@+id/progressBar" • style="?android:attr/progressBarStyleLarge" • mce_style="?android:attr/progressBarStyleLarge" • android:indeterminateDrawable="@drawable/progressbar" • android:layout_width="30dip" • android:layout_height="30dip" • /> • <!-- mce_style="?android:attr/progressBarStyleLarge" --> • <TextView android:layout_height="30dip" android:id="@+id/progress_tv" android:textColor="@color/black" android:layout_width="fill_parent" android:text="@string/loadinfo" /> • </FrameLayout>
Button btaddPic=(Button)this.findViewById(R.id.btGallery); • btaddPic.setOnClickListener(new OnClickListener() • { • @Override • publicvoid onClick(View v) { • Intent i = new Intent("android.media.action.IMAGE_CAPTURE"); • startActivityForResult(i, Activity.DEFAULT_KEYS_DIALER); • } • } • );
protectedvoid onActivityResult(int requestCode, int resultCode, Intent data) { • // TODO Auto-generated method stub • super.onActivityResult(requestCode, resultCode, data); • Bundle extras = data.getExtras(); • Bitmap b = (Bitmap) extras.get("data"); • ByteArrayOutputStream baos = new ByteArrayOutputStream(); • b.compress(Bitmap.CompressFormat.JPEG, 100, baos); • dat = baos.toByteArray(); • this.hasPic=true; • }
地图开发 • Google地图 • Google MAP • 位置导航 • 第三方地图 • 高德
1.获取指纹 C:\Documents and Settings\Administrator>cd C:\Documents and Settings\Administrat or\.android C:\Documents and Settings\Administrator\.android>keytool -list -keystore debug.kEystore 默认密码android 2.申请apikey http://code.google.com/intl/zh-CN/android/maps-api-signup.html
使用Google地图 • MapActivity • 任何显示MapView的Activity都要继承这个类 • 内部封装了访问网络的方法 • MapView • MapController • 控制地图的 移动和缩放 • Overlay • GeoPoint
<uses-library android:name=“com.google.android.maps”> <uses-permission android:name="android.permission.INTERNET"></uses-permission> MapView map=new MapView(this,”key”); Map.setTraffic 地图模式 Map. setSatellite卫星模式 Map.setStreetView街景模式
MapControl=mMapview.getController(); geoPoint=new 成都GeoPoint((int),30.65925*1000000, (int),104.065762*1000000,) mMapController.animateTo(geoPoint);
Public class myLocationOverLay extends OverLay { public boolean draw(Canvas c,mapView m,boolean shadw,long when) { } }
定位系统 • LocationManager • getSystemService(Conext.LOCATION_SERVICE) • 注册周期更新视图的侦听 • Lm.requestLocationUpdates(Locationmanager.GPS_PROVIDER,1000,0,LocationListener) • LocationProvider • LocationListener • onLocationChanged • onProviderDisabled • onproviderEnabled • onStatusChanged • Criteria • GeoCoder
(1) public void setAccuracy( int accuracy ) • 位置解析的精度,高或低,参数: Criteria. ACCURACY_FINE,精确模式; Criteria. ACCURACY_COARSE,模糊模式; • (2) public void setAltitudeRequired(boolean altitudeRequired ) • 是否提供海拔高度信息,是或否 • (3) public void setBearingRequired( boolean bearingRequired ) • 是否提供方向信息,是或否 • (4) public void setCostAllowed( boolean costAllowed ) • 是否允许运营商计费,是或否 • (5) public void setPowerRequirement( int level ) • 电池消耗,无、低、中、高,参数 Criteria. NO_REQUIREMENT, Criteria. POWER_LOW, Criteria. POWER_MEDIUM, or Criteria. POWER_HIGH, • (6) public void setSpeedRequired( boolean speedRequired )
criteria.setAccuracy(ACCURACY_FINE) • ACCURACY_FINE • 精确度设置为模糊解决所有手机无法启动Criteria.ACCURACY_COARSE
Weibo.java新增方法 • public Status uploadStatus(String status,ImageItem item, double latitude, double longitude) throws WeiboException { • returnnew Status(http.multPartURL(getBaseURL() + "statuses/upload.json", • new PostParameter[]{new PostParameter("status", status), • new PostParameter("source", source), • new PostParameter("lat", latitude), • new PostParameter("long", longitude),},item, true)); • /*return new Status(http.multPartURL(getBaseURL() + "statuses/upload.xml", • new PostParameter[]{new PostParameter("status", status), new PostParameter("source", source)},item, true), this);*/ • }
实现TextView局部连接 • start=false; • startIndex=0; • for(int i=0;i<l;i++) • { if(strarray[i]=='#') • { if(!start) • { start=true; • sb=new StringBuffer("weibohuati://view/"); • startIndex=i; • }else • { sb.append('#'); • ss.setSpan(new URLSpan(sb.toString()), startIndex,i+1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); • sb=null; • start=false; • } } • else{ if(start) • {sb.append(strarray[i]); } • } } • textView.setText(ss); textView.setMovementMethod(LinkMovementMethod.getInstance()); • strarray=null; • }}
comment.xml • <?xml version="1.0" encoding="UTF-8"?> • <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" • xmlns:android="http://schemas.android.com/apk/res/android"> • <include android:id="@+id/title" layout="@layout/title_two_button"/> • <LinearLayout android:orientation="vertical" android:background="#fff4f4f4" android:layout_width="fill_parent" android:layout_height="fill_parent"> • <!-- android:visibility="gone" --> • <EditText android:gravity="top" android:id="@id/etCmtReason" android:layout_width="fill_parent" android:layout_height="280.0dip" android:text="" android:singleLine="false" /> • <!-- android:visibility="gone" --> • <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> • <TextView android:textColor="#ff000000" android:id="@id/tvCmtLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="5.0dip" android:layout_marginBottom="3.0dip" android:layout_weight="1.0" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" /> • <RadioButton android:textColor="#ff000000" android:id="@id/rb_forward" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/comment_add_forward" android:layout_below="@id/tvCmtLabel" android:layout_alignParentLeft="true" /> • </RelativeLayout> • <!-- android:visibility="gone" --> • </LinearLayout> • </LinearLayout>
实现Widget • 1.定义Widget的广播 • 2.定义Widget配置文件 • 3.定义Widget布局文件 • 4.定时发送广播给widget在widget的接受器做处理
定义Widget配置 • <receiver android:name="MeWidgetProvider" android:icon="@drawable/boot_robot" android:label="AppWidget Life"> • <intent-filter> • <action android:name="android.appwidget.action.APPWIDGET_UPDATE"> • </action> • <category android:name="android.intent.category.DEFAULT"></category> • </intent-filter> • <meta-data android:resource="@xml/app_widget_info" • android:name="android.appwidget.provider"> • </meta-data> • </receiver>
设置Widget配置文件 • <?xml version="1.0" encoding="UTF-8"?> • <appwidget-provider android:minWidth="300.0dip" • android:minHeight="72.0dip" • android:updatePeriodMillis="0" • android:initialLayout="@layout/weibowidget1" • xmlns:android="http://schemas.android.com/apk/res/android" />
处理Widget事件 • @Override • publicvoid onDisabled(Context context) { • // TODO Auto-generated method stub • super.onDisabled(context); • Intent service=new Intent(WeiboService.START_ACTION); • context.stopService(service); • } • @Override • publicvoid onEnabled(Context context) { • // TODO Auto-generated method stub • super.onEnabled(context); • Intent service=new Intent(WeiboService.START_ACTION); • context.startService(service); • }
publicvoid onReceive(Context context, Intent intent) { • // TODO Auto-generated method stub • super.onReceive(context, intent); • String action=intent.getAction(); • if(action.equals(“WeiboNewInfo”)){ • batterylevel=intent.getIntExtra("level", 0); • batteryImageID=intent.getIntExtra("imageID", 0); • AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); • int[] appWidgetIds=appWidgetManager.getAppWidgetIds( • new ComponentName(context, BatteryAPPWidget.class)); • //更新所有的Widget实例 • onUpdate(context, appWidgetManager, appWidgetIds); • } • }
更新微博显示 • publicvoid onUpdate(Context context, AppWidgetManager appWidgetManager, • int[] appWidgetIds) { • super.onUpdate(context, appWidgetManager, appWidgetIds); • finalint N = appWidgetIds.length; • for (int i=0; i<N; i++) { • int appWidgetId = appWidgetIds[i]; • RemoteViews views = new RemoteViews(context.getPackageName(), • R.layout.battery_widget); • Intent intent = new Intent(Intent.ACTION_VIEW); • PendingIntent pendingIntent= • PendingIntent.getActivity(context, 1,intent, Intent.FLAG_ACTIVITY_NEW_TASK); • views.setOnClickPendingIntent(R.id.widget_battery_image, pendingIntent); • views.setTextViewText(R.id.widget_battery_text, batterylevel+"%"); • appWidgetManager.updateAppWidget(appWidgetId, views); • }