目錄html
第35章圖形和定製視圖
API(Application Programming Interface,應用程序編程接口)是一些預先定義的函數,目的是提供應用程序與開發人員基於某軟件或硬件得以訪問一組例程的能力,而又無需訪問源碼,或理解內部工做機制的細節。
35.2 硬件加速
1.什麼是GPU?
圖形處理器(英語:Graphics Processing Unit,縮寫:GPU),又稱顯示核心、視覺處理器、顯示芯片,是一種專門在我的電腦、工做站、遊戲機和一些移動設備(如平板電腦、智能手機等)上圖像運算工做的微處理器。
2.什麼是GPU加速計算?
GPU 加速計算是指同時利用圖形處理器 (GPU) 和 CPU,加快科學、分析、工程、消費和企業應用程序的運行速度。GPU 加速器於 2007 年由 NVIDIA® 率先推出,現已在世界各地爲政府實驗室、高校、公司以及中小型企業的高能效數據中心提供支持。GPU 可以使從汽車、手機和平板電腦到無人機和機器人等平臺的應用程序加速運行。
3.GPU如何加快軟件應用程序的應用速度?
GPU 加速計算能夠提供非凡的應用程序性能,能將應用程序計算密集部分的工做負載轉移到 GPU,同時仍由 CPU 運行其他程序代碼。從用戶的角度來看,應用程序的運行速度明顯加快。
4.GPU 與 CPU 性能比較?
理解 GPU 和 CPU 之間區別的一種簡單方式是比較它們如何處理任務。CPU 由專爲順序串行處理而優化的幾個核心組成,而 GPU 則擁有一個由數以千計的更小、更高效的核心(專爲同時處理多重任務而設計)組成的大規模並行計算架構。
35.3 建立一個定製視圖
35.4 繪製基本形狀
35.5 繪製文本
35.6 透明度
35.7 Shader
35.8 裁剪
35.9 使用路徑
35.10 CanvasDemo應用程序
1.代碼清單35.1 AndroidManifest.xml文件java
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.canvasdemo" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="18" android:targetSdkVersion="18" /> <application android:hardwareAccelerated="false" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.canvasdemo.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
2.代碼清單35.2 CustomView類android
package com.example.canvasdemo; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Shader; import android.graphics.Typeface; import android.view.View; public class CustomView extends View { public CustomView(Context context) { super(context); } Paint paint = new Paint(Paint.FAKE_BOLD_TEXT_FLAG); Path starPath; Path curvePath; Paint textPaint = new Paint(Paint.LINEAR_TEXT_FLAG); Paint shaderPaint = new Paint(); { Typeface typeface = Typeface.create( Typeface.SERIF, Typeface.BOLD); textPaint.setTypeface(typeface); Shader shader = new LinearGradient(0, 400, 300, 500, Color.RED, Color.GREEN, Shader.TileMode.CLAMP); shaderPaint.setShader(shader); // create star path starPath = createStarPath(300, 500); curvePath = createCurvePath(); } protected void onDraw(Canvas canvas) { // draw basic shapes canvas.drawLine(5, 5, 200, 5, paint); canvas.drawLine(5, 15, 200, 15, paint); canvas.drawLine(5, 25, 200, 25, paint); paint.setColor(Color.YELLOW); canvas.drawCircle(50, 70, 35, paint); paint.setColor(Color.GREEN); canvas.drawRect(new Rect(100, 60, 150, 80), paint); paint.setColor(Color.DKGRAY); canvas.drawOval(new RectF(160, 60, 250, 80), paint); // draw text textPaint.setTextSize(22); canvas.drawText("Welcome", 20, 150, textPaint); textPaint.setColor(Color.MAGENTA); textPaint.setTextSize(40); canvas.drawText("Welcome", 20, 190, textPaint); // transparency textPaint.setColor(0xFF465574); textPaint.setTextSize(60); canvas.drawText("Android Rocks", 20, 340, textPaint); // opaque circle canvas.drawCircle(80, 300, 20, paint); // semi-transparent circle paint.setAlpha(110); canvas.drawCircle(160, 300, 39, paint); paint.setColor(Color.YELLOW); paint.setAlpha(140); canvas.drawCircle(240, 330, 30, paint); paint.setColor(Color.MAGENTA); paint.setAlpha(30); canvas.drawCircle(288, 350, 30, paint); paint.setColor(Color.CYAN); paint.setAlpha(100); canvas.drawCircle(380, 330, 50, paint); // draw text on path textPaint.setColor(Color.rgb(155, 20, 10)); canvas.drawTextOnPath("Nice artistic touches", curvePath, 10, 10, textPaint); // shader canvas.drawRect(0, 400, 200, 500, shaderPaint); // create a star-shaped clip canvas.drawPath(starPath, textPaint); textPaint.setColor(Color.CYAN); canvas.clipPath(starPath); textPaint.setColor(Color.parseColor("yellow")); canvas.drawText("Android", 350, 550, textPaint); textPaint.setColor(Color.parseColor("#abde97")); canvas.drawText("Android", 400, 600, textPaint); canvas.drawText("Android Rocks", 300, 650, textPaint); canvas.drawText("Android Rocks", 320, 700, textPaint); canvas.drawText("Android Rocks", 360, 750, textPaint); canvas.drawText("Android Rocks", 320, 800, textPaint); } private Path createStarPath(int x, int y) { Path path = new Path(); path.moveTo(0 + x, 150 + y); path.lineTo(120 + x, 140 + y); path.lineTo(150 + x, 0 + y); path.lineTo(180 + x, 140 + y); path.lineTo(300 + x, 150 + y); path.lineTo(200 + x, 190 + y); path.lineTo(250 + x, 300 + y); path.lineTo(150 + x, 220 + y); path.lineTo(50 + x, 300 + y); path.lineTo(100 + x, 190 + y); path.lineTo(0 + x, 150 + y); return path; } private Path createCurvePath() { Path path = new Path(); path.addArc(new RectF(400, 40, 780, 300), -210, 230); return path; } }
3.代碼清單35.3 MainActivity類git
package com.example.canvasdemo; import android.app.Activity; import android.os.Bundle; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); CustomView customView = new CustomView(this); setContentView(customView); }
第36章片斷
片斷是可以嵌入到活動中的組件。和定製視圖不一樣,片斷有本身的生命週期,而且能夠有,也能夠沒有用戶界面。
36.1 片斷的生命週期
1.Android四大組件的生命週期
(1)Service生命週期
(2)Activity生命週期
(3)片斷生命週期
(4)Activity與片斷生命週期的對比
片斷所在的 Activity 的生命週期會直接影響片斷的生命週期,其表現爲,Activity 的每次生命週期回調都會引起每一個片斷的相似回調。 例如,當 Activity 收到 onPause() 時,Activity 中的每一個片斷也會收到 onPause()。不過,片斷還有幾個額外的生命週期回調,用於處理與 Activity 的惟一交互,以執行構建和銷燬片斷 UI 等操做。 這些額外的回調方法是:
onAttach()
在片斷已與 Activity 關聯時調用(Activity 傳遞到此方法內)。
onCreateView()
調用它可建立與片斷關聯的視圖層次結構。
onActivityCreated()
在 Activity 的 onCreate() 方法已返回時調用。
onDestroyView()
在移除與片斷關聯的視圖層次結構時調用。
onDetach()
在取消片斷與 Activity 的關聯時調用。
圖示說明了受其宿主 Activity 影響的片斷生命週期流。在該圖中,您能夠看到 Activity 的每一個連續狀態如何決定片斷能夠收到的回調方法。 例如,當 Activity 收到其 onCreate() 回調時,Activity 中的片斷只會收到 onActivityCreated() 回調。
一旦 Activity 達到恢復狀態,您就能夠隨意向 Activity 添加片斷和移除其中的片斷。 所以,只有當 Activity 處於恢復狀態時,片斷的生命週期才能獨立變化。
不過,當 Activity 離開恢復狀態時,片斷會在 Activity 的推進下再次經歷其生命週期。
36.3 使用片斷
1.代碼清單36.1 FragmentDemo1的AndroidManifest.xml文件正則表達式
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.fragmentdemo1" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="18" android:targetSdkVersion="18" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme"> <activity android:name="com.example.fragmentdemo1.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
2.代碼清單36.2 主活動的佈局文件編程
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:name="com.example.fragmentdemo1.NamesFragment" android:id="@+id/namesFragment" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent" /> <fragment android:name="com.example.fragmentdemo1.DetailsFragment" android:id="@+id/detailsFragment" android:layout_weight="2.5" android:layout_width="0dp" android:layout_height="match_parent" /> </LinearLayout>
3.代碼清單36.3 fragment_names.xml文件canvas
<ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/listView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#FFFF55"/>
4.代碼清單36.4 NamesFragment類數組
package com.example.fragmentdemo1; import android.app.Activity; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; public class NamesFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final String[] names = {"Amsterdam", "Brussels", "Paris"}; // use android.R.layout.simple_list_item_activated_1 // to have the selected item in a different color ArrayAdapter<String> adapter = new ArrayAdapter<String>( getActivity(), android.R.layout.simple_list_item_activated_1, names); View view = inflater.inflate(R.layout.fragment_names, container, false); final ListView listView = (ListView) view.findViewById( R.id.listView1); listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, final View view, int position, long id) { if (callback != null) { callback.onItemSelected(names[position]); } } }); listView.setAdapter(adapter); return view; } public interface Callback { public void onItemSelected(String id); } private Callback callback; @Override public void onAttach(Activity activity) { super.onAttach(activity); if (activity instanceof Callback) { callback = (Callback) activity; } } @Override public void onDetach() { super.onDetach(); callback = null; } }
5.代碼清單36.5 fragment_details.xml文件android-studio
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:background="#FAFAD2" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="30sp"/> <ImageView android:id="@+id/imageView1" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>
6.代碼清單36.6 DetailsFragment類架構
package com.example.fragmentdemo1; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.ImageView.ScaleType; import android.widget.TextView; public class DetailsFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_details, container, false); } public void showDetails(String name) { TextView textView = (TextView) getView().findViewById(R.id.text1); textView.setText(name); ImageView imageView = (ImageView) getView().findViewById( R.id.imageView1); imageView.setScaleType(ScaleType.FIT_XY); // stretch image if (name.equals("Amsterdam")) { imageView.setImageResource(R.drawable.amsterdam); } else if (name.equals("Brussels")) { imageView.setImageResource(R.drawable.brussels); } else if (name.equals("Paris")) { imageView.setImageResource(R.drawable.paris); } } }
7.代碼清單36.7 FragmentDemo1的活動類
package com.example.fragmentdemo1; import android.app.Activity; import android.os.Bundle; public class MainActivity extends Activity implements NamesFragment.Callback { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public void onItemSelected(String value) { DetailsFragment details = (DetailsFragment) getFragmentManager().findFragmentById( R.id.detailsFragment); details.showDetails(value); } }
小嚐試:增添了一個Beijing選項❤ |
36.4 擴展ListFragment並使用FragmentManager
1.代碼清單36.8 NamesListFragment類
package com.example.fragmentdemo2; import android.app.Activity; import android.app.ListFragment; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; /* we don't need fragment_names-xml anymore */ public class NamesListFragment extends ListFragment { final String[] names = {"Amsterdam", "Brussels", "Paris"}; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ArrayAdapter<String> adapter = new ArrayAdapter<String>( getActivity(), android.R.layout.simple_list_item_activated_1, names); setListAdapter(adapter); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { // ListView can only be accessed here, not in onCreate() super.onViewCreated(view, savedInstanceState); ListView listView = getListView(); listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, final View view, int position, long id) { if (callback != null) { callback.onItemSelected(names[position]); } } }); } public interface Callback { public void onItemSelected(String id); } private Callback callback; @Override public void onAttach(Activity activity) { super.onAttach(activity); if (activity instanceof Callback) { callback = (Callback) activity; } } @Override public void onDetach() { super.onDetach(); callback = null; } }
2.代碼清單36.9 DetailsFragment類
package com.example.fragmentdemo2; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.ImageView.ScaleType; import android.widget.TextView; public class DetailsFragment extends Fragment { int imageId; String name; public DetailsFragment() { } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments().containsKey("name")) { name = getArguments().getString("name"); } if (getArguments().containsKey("imageId")) { imageId = getArguments().getInt("imageId"); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate( R.layout.fragment_details, container, false); TextView textView = (TextView) rootView.findViewById(R.id.text1); textView.setText(name); ImageView imageView = (ImageView) rootView.findViewById( R.id.imageView1); imageView.setScaleType(ScaleType.FIT_XY); //stretch image imageView.setImageResource(imageId); return rootView; } }
3.代碼清單36.10 activity_main.xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:name="com.example.fragmentdemo2.NamesListFragment" android:id="@+id/namesFragment" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <FrameLayout android:id="@+id/details_container" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="2.5"/> </LinearLayout>
4.代碼清單36.11 MainActivity類
package com.example.fragmentdemo2; import android.app.Activity; import android.app.FragmentManager; import android.app.FragmentTransaction; import android.os.Bundle; public class MainActivity extends Activity implements NamesListFragment.Callback { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public void onItemSelected(String value) { Bundle arguments = new Bundle(); arguments.putString("name", value); if (value.equals("Amsterdam")) { arguments.putInt("imageId", R.drawable.amsterdam); } else if (value.equals("Brussels")) { arguments.putInt("imageId", R.drawable.brussels); } else if (value.equals("Paris")) { arguments.putInt("imageId", R.drawable.paris); } DetailsFragment fragment = new DetailsFragment(); fragment.setArguments(arguments); FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.replace( R.id.details_container, fragment); fragmentTransaction.commit(); } }
第37章多面板佈局
37.1 概覽
若是要編寫一個在兩種類型的設備上顯示得不錯的應用程序,一般的策略是支持兩種佈局。能夠對手機使用單面板的佈局,而對平板電腦使用多面板的佈局。
這裏,dp表示獨立的像素的密度。能夠經過dp和屏幕密度(每英寸中的點的數目,或dpi)來計算像素數目。
px=dp*(dpi/160)
在Android3.2及其之後的版本中,使用一種新的技術,根據dp爲單位的空間量來度量屏幕,而不是隻使用4種屏幕大小,並試圖讓佈局適應通用的大小分組。
37.2 多面板示例
1.代碼清單37.1 AndroidManifest.xml文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.multipanedemo" > <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".ItemListActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".ItemDetailActivity" android:label="@string/title_item_detail" android:parentActivityName=".ItemListActivity" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".ItemListActivity" /> </activity> </application> </manifest>
2.代碼清單37.2 ItemListActivity類
package com.example.multipanedemo; import android.app.Activity; import android.content.Intent; import android.os.Bundle; public class ItemListActivity extends Activity implements ItemListFragment.Callbacks { private boolean twoPane; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_item_list); if (findViewById(R.id.item_detail_container) != null) { twoPane = true; // In two-pane mode, list items should be given the // 'activated' state when touched. ((ItemListFragment) getFragmentManager() .findFragmentById(R.id.item_list)) .setActivateOnItemClick(true); } } /** * Callback method from {@link ItemListFragment.Callbacks} * indicating that the item with the given ID was selected. */ @Override public void onItemSelected(String id) { if (twoPane) { Bundle arguments = new Bundle(); arguments.putString(ItemDetailFragment.ARG_ITEM_ID, id); ItemDetailFragment fragment = new ItemDetailFragment(); fragment.setArguments(arguments); getFragmentManager().beginTransaction() .replace(R.id.item_detail_container, fragment) .commit(); } else { // In single-pane mode, simply start the detail activity // for the selected item ID. Intent detailIntent = new Intent(this, ItemDetailActivity.class); detailIntent.putExtra(ItemDetailFragment.ARG_ITEM_ID, id); startActivity(detailIntent); } } }
3.代碼清單37.3 res/layout-sw600dp/activity_item_list.xml文件(用於多面板)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" android:baselineAligned="false" android:divider="?android:attr/dividerHorizontal" android:orientation="horizontal" android:showDividers="middle" tools:context=".ItemListActivity"> <!-- This layout is a two-pane layout for the Items master/detail flow. --> <fragment android:id="@+id/item_list" android:name="com.example.multipanedemo.ItemListFragment" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" tools:layout="@android:layout/list_content" /> <FrameLayout android:id="@+id/item_detail_container" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="3" /> </LinearLayout>
4.代碼清單37.4 fragment_item_detail.xml文件
<TextView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/item_detail" style="?android:attr/textAppearanceLarge" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp" android:textIsSelectable="true" tools:context=".ItemDetailFragment" />
5.代碼清單37.5 res/layout/activity_item_list.xml file(用於單面板)
<fragment xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/item_list" android:name="com.example.multipanedemo.ItemListFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" tools:context=".ItemListActivity" tools:layout="@android:layout/list_content" />
6.代碼清單37.6 ItemListFragment類
package com.example.multipanedemo; import android.app.Activity; import android.os.Bundle; import android.app.ListFragment; import android.view.View; import android.widget.ArrayAdapter; import android.widget.ListView; import com.example.multipanedemo.dummy.DummyContent; public class ItemListFragment extends ListFragment { private static final String STATE_ACTIVATED_POSITION = "activated_position"; /** * The fragment's current callback object, which is notified of list item * clicks. */ private Callbacks mCallbacks = sDummyCallbacks; /** * The current activated item position. Only used on tablets. */ private int mActivatedPosition = ListView.INVALID_POSITION; /** * A callback interface that all activities containing this fragment must * implement. This mechanism allows activities to be notified of item * selections. */ public interface Callbacks { /** * Callback for when an item has been selected. */ public void onItemSelected(String id); } /** * A dummy implementation of the {@link Callbacks} interface that does * nothing. Used only when this fragment is not attached to an activity. */ private static Callbacks sDummyCallbacks = new Callbacks() { @Override public void onItemSelected(String id) { } }; /** * Mandatory empty constructor for the fragment manager to instantiate the * fragment (e.g. upon screen orientation changes). */ public ItemListFragment() { } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // TODO: replace with a real list adapter. setListAdapter(new ArrayAdapter<DummyContent.DummyItem>( getActivity(), android.R.layout.simple_list_item_activated_1, android.R.id.text1, DummyContent.ITEMS)); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // Restore the previously serialized activated item position. if (savedInstanceState != null && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) { setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION)); } } @Override public void onAttach(Activity activity) { super.onAttach(activity); // Activities containing this fragment must implement its callbacks. if (!(activity instanceof Callbacks)) { throw new IllegalStateException("Activity must implement fragment's callbacks."); } mCallbacks = (Callbacks) activity; } @Override public void onDetach() { super.onDetach(); // Reset the active callbacks interface to the dummy implementation. mCallbacks = sDummyCallbacks; } @Override public void onListItemClick(ListView listView, View view, int position, long id) { super.onListItemClick(listView, view, position, id); // Notify the active callbacks interface (the activity, if the // fragment is attached to one) that an item has been selected. mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if (mActivatedPosition != ListView.INVALID_POSITION) { // Serialize and persist the activated item position. outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition); } } /** * Turns on activate-on-click mode. When this mode is on, list items will be * given the 'activated' state when touched. */ public void setActivateOnItemClick(boolean activateOnItemClick) { // When setting CHOICE_MODE_SINGLE, ListView will automatically // give items the 'activated' state when touched. getListView().setChoiceMode(activateOnItemClick ? ListView.CHOICE_MODE_SINGLE : ListView.CHOICE_MODE_NONE); } private void setActivatedPosition(int position) { if (position == ListView.INVALID_POSITION) { getListView().setItemChecked(mActivatedPosition, false); } else { getListView().setItemChecked(position, true); } mActivatedPosition = position; } }
7.代碼清單37.7 ItemDetailFragment類
package com.example.multipanedemo; import android.os.Bundle; import android.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.example.multipanedemo.dummy.DummyContent; /** * A fragment representing a single Item detail screen. * This fragment is either contained in a {@link ItemListActivity} * in two-pane mode (on tablets) or a {@link ItemDetailActivity} * on handsets. */ public class ItemDetailFragment extends Fragment { /** * The fragment argument representing the item ID that this fragment * represents. */ public static final String ARG_ITEM_ID = "item_id"; /** * The dummy content this fragment is presenting. */ private DummyContent.DummyItem mItem; /** * Mandatory empty constructor for the fragment manager to instantiate the * fragment (e.g. upon screen orientation changes). */ public ItemDetailFragment() { } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments().containsKey(ARG_ITEM_ID)) { // Load the dummy content specified by the fragment // arguments. In a real-world scenario, use a Loader // to load content from a content provider. mItem = DummyContent.ITEM_MAP.get(getArguments().getString(ARG_ITEM_ID)); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_item_detail, container, false); // Show the dummy content as text in a TextView. if (mItem != null) { ((TextView) rootView.findViewById(R.id.item_detail)).setText(mItem.content); } return rootView; } }
平板電腦——
手機——
第38章動畫
38.2 屬性動畫
38.2.1 Animator
設置目標對象;設置時長;啓動動畫
38.2.2 ValueAnimator
ValueAnimator經過計算一個從起始值向最終值過渡的一個值,從而建立動畫。
38.2.3 ObjectAnimator
38.2.4 AnimatorSet
以必定的順序播放一組動畫。
38.3 動畫項目
1.代碼清單38.1 AnimationDemo的清單文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.animationdemo" > <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.animationdemo.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
2.代碼清單38.2 activity_main.xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context=".MainActivity" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:id="@+id/button1" android:text="@string/button_animate1" android:textColor="#ff4433" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="animate1"/> <Button android:id="@+id/button2" android:text="@string/button_animate2" android:textColor="#33ff33" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="animate2"/> <Button android:id="@+id/button3" android:text="@string/button_animate3" android:textColor="#3398ff" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="animate3"/> </LinearLayout> <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top|center" android:src="@drawable/photo1" /> </LinearLayout>
3.代碼清單38.3 MainActivity類
package com.example.animationdemo; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.View; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } public void animate1(View source) { View view = findViewById(R.id.imageView1); ObjectAnimator objectAnimator = ObjectAnimator.ofFloat( view, "rotationY", 0F, 720.0F); objectAnimator.setDuration(2000); objectAnimator.start(); } public void animate2(View source) { final View view = findViewById(R.id.imageView1); ValueAnimator valueAnimator = ValueAnimator.ofFloat(0F, 7200F); valueAnimator.setDuration(15000); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Float value = (Float) animation.getAnimatedValue(); view.setRotationX(value); if (value < 3600) { view.setTranslationX(value/20); view.setTranslationY(value/20); } else { view.setTranslationX((7200-value)/20); view.setTranslationY((7200-value)/20); } } }); valueAnimator.start(); } public void animate3(View source) { View view = findViewById(R.id.imageView1); ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(view, "translationY", 0F, 300.0F); ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(view, "translationX", 0F, 300.0F); objectAnimator1.setDuration(2000); objectAnimator2.setDuration(2000); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether(objectAnimator1, objectAnimator2); ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(view, "rotation", 0F, 1440F); objectAnimator3.setDuration(4000); animatorSet.play(objectAnimator3).after(objectAnimator2); animatorSet.start(); } }
5.An array cannot hold object types.(數組中不能包含對象類型)
A .True
B .False
正確答案: B 個人答案: A
錯誤緣由:數組中能夠包含對象類型。
12.Which of the following method declarations correctly defines a method with a variable length parameter list?(下面哪一個方法聲明正肯定義了一個變長參數的方法)
A .public int average(int[] list)
B .public int average(int ... list)
C .public int average( ... )
D .public int average(int a, int b, int c, ...)
E .public int average(integers)
正確答案: B 個人答案: D
錯誤緣由:惟一具備有效語法的選項是選項A和選項B。選項A表示具備單個參數的方法聲明,該參數是對數組的引用。選項B正確地表示具備可變長度參數列表的方法的有效聲明。
https://gitee.com/EvelynYang/ninth_weeks
在新建的AndroidProjects文件夾中運行腳本,第六週及以前都是在IdeaProjects文件夾裏運行。
代碼行數(新增/累積) | 博客量(新增/累積) | 學習時間(新增/累積) | 重要成長 | |
---|---|---|---|---|
目標 | 5000行 | 30篇 | 400小時 | |
第一週 | 200/200 | 2/2 | 20/20 | |
第二週 | 300/500 | 1/3 | 18/38 | |
第三週 | 500/1000 | 1/4 | 38/76 | |
第四周 | 1000/2000 | 1/5 | 20/96 | |
第五週 | 1000/3000 | 1/6 | 25/121 | |
第六週 | 1000/4000 | 1/7 | 25/146 | |
第七週 | 1000/5000 | 1/8 | 25/171 | |
第八週 | 1000/6000 | 1/9 | 15/186 | |
第九周 | 1000/7000 | 1/10 | 20/206 |