目录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 |