Lab - Intents
启动程序
private void startExplicitActivation() { Log.i(TAG,"Entered startExplicitActivation()"); // TODO - Create a new intent to launch the ExplicitlyLoadedActivity class Intent intent=new Intent(ActivityLoaderActivity.this, ExplicitlyLoadedActivity.class); startActivityForResult(intent, 0); // TODO - Start an Activity using that intent and the request code defined above }
private void startImplicitActivation() { Log.i(TAG, "Entered startImplicitActivation()"); // TODO - Create a base intent for viewing a URL // (HINT: second parameter uses parse() from the Uri class) Uri webpage = Uri.parse("http://www.google.com"); Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage); // TODO - Create a chooser intent, for choosing which Activity // will carry out the baseIntent. Store the Intent in the // chooserIntent variable below. HINT: using the Intent class' // createChooser Intent chooserIntent = Intent.createChooser(webIntent, "CHOOSER"); Log.i(TAG,"Chooser Intent Action:" + chooserIntent.getAction()); // TODO - Start the chooser Activity, using the chooser intent startActivity(chooserIntent); }
关联程序
<activity android:name=".MyBrowserActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="http" /> </intent-filter> <!-- TODO - Add necessary intent filter information so that this Activity will accept Intents with the action "android.intent.action.VIEW" and with an "http" schemed URL --> </activity>
Lab - Permissions
读取书签--使用权限
<uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/>
private void loadBookmarks() { Log.i(TAG, "Entered loadBookmarks()"); String text = ""; Cursor query = getContentResolver().query(Browser.BOOKMARKS_URI, projection, null, null, null); query.moveToFirst(); while (query.moveToNext()) { text += query.getString(query .getColumnIndex(Browser.BookmarkColumns.TITLE)); text += " "; text += query.getString(query .getColumnIndex(Browser.BookmarkColumns.URL)); text += " "; } TextView box = (TextView) findViewById(R.id.text); box.setText(text); Log.i(TAG, "Bookmarks loaded"); }
自定义权限
<permission android:name="course.labs.permissions.DANGEROUS_ACTIVITY_PERM" android:protectionLevel="dangerous"></permission> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <!-- TODO - enforce the custom permission on this Activity --> <activity android:name=".DangerousActivity" android:label="@string/app_name" > <!-- TODO - add additional intent filter info so that this Activity will respond to an Implicit Intent with the action "course.labs.permissions.DANGEROUS_ACTIVITY" --> <intent-filter> <action android:name="android.intent.action.MAIN" /> <action android:name="course.labs.permissions.DANGEROUS_ACTIVITY"/> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
Lab - The Fragment Class
主activity定义layout
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent" />
添加fragment
mFriendsFragment = new FriendsFragment(); //TODO 1 - add the FriendsFragment to the fragment_container FragmentTransaction a=getFragmentManager().beginTransaction(); a.add(R.id.fragment_container,mFriendsFragment); a.commit();
替换fragment
//TODO 2 - replace the fragment_container with the FeedFragment getFragmentManager().beginTransaction().replace( R.id.fragment_container, mFeedFragment).commit(); // execute transaction now getFragmentManager().executePendingTransactions();
// Update Twitter feed display on FriendFragment
mFeedFragment.updateFeedDisplay(position);
判断fragment状态
// If there is no fragment_container ID, then the application is in // two-pane mode private boolean isInTwoPaneMode() { return findViewById(R.id.fragment_container) == null; }
Lab - User Interface Classes
用户设定日期
public static class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the current date as the default date in the picker final Calendar c = Calendar.getInstance(); int year = c.get(Calendar.YEAR); int month = c.get(Calendar.MONTH); int day = c.get(Calendar.DAY_OF_MONTH); // Create a new instance of DatePickerDialog and return it return new DatePickerDialog(getActivity(), this, year, month, day); } @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { setDateString(year, monthOfYear, dayOfMonth); dateView.setText(dateString); } } private void showDatePickerDialog() { DialogFragment newFragment = new DatePickerFragment(); newFragment.show(getFragmentManager(), "datePicker"); } private static void setDateString(int year, int monthOfYear, int dayOfMonth) { // Increment monthOfYear for Calendar/Date -> Time Format setting monthOfYear++; String mon = "" + monthOfYear; String day = "" + dayOfMonth; if (monthOfYear < 10) mon = "0" + monthOfYear; if (dayOfMonth < 10) day = "0" + dayOfMonth; dateString = year + "-" + mon + "-" + day; }
用户设定时间
// DialogFragment used to pick a ToDoItem deadline time public static class TimePickerFragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the current time as the default values for the picker final Calendar c = Calendar.getInstance(); int hour = c.get(Calendar.HOUR_OF_DAY); int minute = c.get(Calendar.MINUTE); // Create a new instance of TimePickerDialog and return return new TimePickerDialog(getActivity(), this, hour, minute, true); } public void onTimeSet(TimePicker view, int hourOfDay, int minute) { setTimeString(hourOfDay, minute, 0); timeView.setText(timeString); } } private void showTimePickerDialog() { DialogFragment newFragment = new TimePickerFragment(); newFragment.show(getFragmentManager(), "timePicker"); } private static void setTimeString(int hourOfDay, int minute, int mili) { String hour = "" + hourOfDay; String min = "" + minute; if (hourOfDay < 10) hour = "0" + hourOfDay; if (minute < 10) min = "0" + minute; timeString = hour + ":" + min + ":00"; }
设定默认日期时间
// Use this method to set the default date and time private void setDefaultDateTime() { mDate = new Date(); mDate = new Date(mDate.getTime()); Calendar c = Calendar.getInstance(); c.setTime(mDate); setDateString(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH)); dateView.setText(dateString); setTimeString(c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), c.get(Calendar.MILLISECOND)); timeView.setText(timeString); }
使用BaseAdapter实现复杂的ListView(转)原文链接
package com.app.weixin; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import com.app.wexin.R; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; public class WeixinActivity extends Activity { private ImageView img; private List<HashMap<String, Object>> mData; private ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.friend_list); mData = getData();//为刚才的变量赋值 MyAdapter adapter = new MyAdapter(this);//创建一个适配器 listView = (ListView) findViewById(R.id.listView1);//实例化ListView listView.setAdapter(adapter);//为ListView控件绑定适配器 } /** 自定义适配器 */ public class MyAdapter extends BaseAdapter { private LayoutInflater mInflater;// 动态布局映射 public MyAdapter(Context context) { this.mInflater = LayoutInflater.from(context); } // 决定ListView有几行可见 @Override public int getCount() { return mData.size();// ListView的条目数 } @Override public Object getItem(int arg0) { return null; } @Override public long getItemId(int arg0) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { convertView = mInflater.inflate(R.layout.friend_list_item, null);//根据布局文件实例化view TextView title = (TextView) convertView.findViewById(R.id.title);//找某个控件 title.setText(mData.get(position).get("title").toString());//给该控件设置数据(数据从集合类中来) TextView time = (TextView) convertView.findViewById(R.id.time);//找某个控件 time.setText(mData.get(position).get("time").toString());//给该控件设置数据(数据从集合类中来) TextView info = (TextView) convertView.findViewById(R.id.info); info.setText(mData.get(position).get("info").toString()); img = (ImageView) convertView.findViewById(R.id.img); img.setBackgroundResource((Integer) mData.get(position).get("img")); return convertView; } } // 初始化一个List private List<HashMap<String, Object>> getData() { // 新建一个集合类,用于存放多条数据 ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>(); HashMap<String, Object> map = null; for (int i = 1; i <= 40; i++) { map = new HashMap<String, Object>(); map.put("title", "人物" + i); map.put("time", "9月20日"); map.put("info", "我通过了你的好友验证请求"); map.put("img", R.drawable.pic_person); list.add(map); } return list; } public void showInfo(int position){ getData(); } }
Lab - Notifications
注册broadcast receiver
public static final String DATA_REFRESHED_ACTION = "course.labs.notificationslab.DATA_REFRESHED"; private BroadcastReceiver mRefreshReceiver; registerReceiver(mRefreshReceiver, new IntentFilter(DATA_REFRESHED_ACTION)); unregisterReceiver(mRefreshReceiver);
final PendingIntent pendingIntent = PendingIntent.getActivity(mParentActivity, 0, restartMainActivtyIntent, PendingIntent.FLAG_UPDATE_CURRENT); // Uses R.layout.custom_notification for the // layout of the notification View. The xml // file is in res/layout/custom_notification.xml RemoteViews mContentView = new RemoteViews( mApplicationContext.getPackageName(), R.layout.custom_notification); // TODO: Set the notification View's text to // reflect whether or the download completed // successfully mContentView.setTextViewText(R.id.text, successMsg); // TODO: Use the Notification.Builder class to // create the Notification. You will have to set // several pieces of information. You can use // android.R.drawable.stat_sys_warning // for the small icon. You should also setAutoCancel(true). Notification.Builder notificationBuilder = new Notification.Builder( mParentActivity) .setSmallIcon(android.R.drawable.stat_sys_warning) .setAutoCancel(true) .setContent(mContentView) .setContentIntent(pendingIntent); // TODO: Send the notification // Pass the Notification to the NotificationManager: NotificationManager mNotificationManager = (NotificationManager) mParentActivity.getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.notify(MY_NOTIFICATION_ID, notificationBuilder.build());
Lab - Graphics(Gesture)
mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() { // If a fling gesture starts on a BubbleView then change the // BubbleView's velocity @Override public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) { // TODO - Implement onFling actions. // You can get all Views in mFrame using the // ViewGroup.getChildCount() method for(int i=0;i<mFrame.getChildCount();i++){ BubbleView bubbleNew= (BubbleView) mFrame.getChildAt(i); if (bubbleNew.intersects(event1.getX(),event1.getY())){ bubbleNew.deflect(velocityX, velocityY); return true; } } return false; } // If a single tap intersects a BubbleView, then pop the BubbleView // Otherwise, create a new BubbleView at the tap's location and add // it to mFrame. You can get all views from mFrame with ViewGroup.getChildAt() @Override public boolean onSingleTapConfirmed(MotionEvent event) { // TODO - Implement onSingleTapConfirmed actions. // You can get all Views in mFrame using the // ViewGroup.getChildCount() method for(int i=0;i<mFrame.getChildCount();i++){ BubbleView bubbleNew= (BubbleView) mFrame.getChildAt(i); if (bubbleNew.intersects(event.getX(),event.getY())){ //sound now return true; } } BubbleView bubbleView = new BubbleView(getApplicationContext(), event.getX(), event.getY()); mFrame.addView(bubbleView); bubbleView.start(); return true; } });
@Override public boolean onTouchEvent(MotionEvent event) { // TODO - delegate the touch to the gestureDetector return mGestureDetector.onTouchEvent(event); }
定时任务
// Start moving the BubbleView & updating the display private void start() { // Creates a WorkerThread ScheduledExecutorService executor = Executors .newScheduledThreadPool(1); // Execute the run() in Worker Thread every REFRESH_RATE // milliseconds // Save reference to this job in mMoverFuture mMoverFuture = executor.scheduleWithFixedDelay(new Runnable() { @Override public void run() { // TODO - implement movement logic. // Each time this method is run the BubbleView should // move one step. If the BubbleView exits the display, // stop the BubbleView's Worker Thread. // Otherwise, request that the BubbleView be redrawn. if(moveWhileOnScreen()){ stop(false); }else{ postInvalidate(); } } }, 0, REFRESH_RATE, TimeUnit.MILLISECONDS); }
// Draw the Bubble at its current location @Override protected synchronized void onDraw(Canvas canvas) { super.onDraw(canvas); // TODO - save the canvas canvas.save(); // TODO - increase the rotation of the original image by mDRotate mRotate += mDRotate; // TODO Rotate the canvas by current rotation canvas.rotate(mRotate, mXPos + mScaledBitmapWidth/2, mYPos + mScaledBitmapWidth/2); // TODO - draw the bitmap at it's new location canvas.drawBitmap(mScaledBitmap, mXPos, mYPos, mPainter); // TODO - restore the canvas canvas.restore(); }
注意canvas中画的图坐标不是在中心,而是左上角
// Sound variables // AudioManager private AudioManager mAudioManager; // SoundPool private SoundPool mSoundPool; // ID for the bubble popping sound private int mSoundID; // Audio volume private float mStreamVolume; // Manage bubble popping sound // Use AudioManager.STREAM_MUSIC as stream type mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE); mStreamVolume = (float) mAudioManager .getStreamVolume(AudioManager.STREAM_MUSIC) / mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); // TODO - make a new SoundPool, allowing up to 10 streams mSoundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0); // TODO - set a SoundPool OnLoadCompletedListener that calls setupGestureDetector() mSoundPool.setOnLoadCompleteListener(new OnLoadCompleteListener(){ @Override public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { if (0 == status) { setupGestureDetector(); } } }); // TODO - load the sound from res/raw/bubble_pop.wav mSoundID = mSoundPool.load(this, R.raw.bubble_pop, 1);
mSoundPool.play(mSoundID, mStreamVolume, mStreamVolume, 1, 0, 1.0f);