1page.title=Định nghĩa Hoạt hình Tùy chỉnh 2 3@jd:body 4 5<div id="tb-wrapper"> 6<div id="tb"> 7<h2>Bài học này hướng dẫn bạn cách</h2> 8<ol> 9 <li><a href="#Touch">Tùy chỉnh Phản hồi Chạm</a></li> 10 <li><a href="#Reveal">Sử dụng Hiệu ứng Lộ ra</a></li> 11 <li><a href="#Transitions">Tùy chỉnh Chuyển tiếp Hoạt động</a></li> 12 <li><a href="#ViewState">Tạo Hiệu ứng Hoạt hình Thay đổi Trạng thái Xem</a></li> 13 <li><a href="#AnimVector">Tạo Hiệu ứng Hoạt hình Nội dung vẽ được Véc-tơ</a></li> 14</ol> 15<h2>Bạn cũng nên đọc</h2> 16<ul> 17 <li><a href="http://www.google.com/design/spec">Đặc tả phong cách Material Design</a></li> 18 <li><a href="{@docRoot}design/material/index.html">Material Design trên Android</a></li> 19</ul> 20</div> 21</div> 22 23 24<p>Hoạt hình theo phong cách material design phản hồi hành động của người dùng và cung cấp 25tính liên tục trực quan khi người dùng tương tác với ứng dụng của bạn. Giao diện material cung cấp một số hoạt hình 26mặc định cho các nút và chuyển tiếp hoạt động, và Android 5.0 (API mức 21) và cao hơn cho phép bạn tùy chỉnh 27những hoạt hình này và tạo các hoạt hình mới:</p> 28 29<ul> 30<li>Phản hồi chạm</li> 31<li>Lộ ra Vòng tròn</li> 32<li>Chuyển tiếp hoạt động</li> 33<li>Chuyển động cong</li> 34<li>Thay đổi trạng thái xem</li> 35</ul> 36 37 38<h2 id="Touch">Tùy chỉnh Phản hồi Chạm</h2> 39 40<p>Phản hồi chạm trong Material Design đưa ra một xác nhận trực quan tức thời tại 41điểm tiếp xúc khi người dùng tương tác với các phần tử UI. Hoạt hình phản hồi chạm mặc định 42cho nút sẽ sử dụng lớp {@link android.graphics.drawable.RippleDrawable} mới để chuyển tiếp 43giữa các trạng thái khác nhau bằng hiệu ứng gợn sóng.</p> 44 45<p>Trong hầu hết trường hợp, bạn nên áp dụng tính năng này trong tệp XML dạng xem của mình bằng cách chỉ định nền 46dạng xem là:</p> 47 48<ul> 49<li><code>?android:attr/selectableItemBackground</code> cho gợn sóng có giới hạn.</li> 50<li><code>?android:attr/selectableItemBackgroundBorderless</code> cho gợn sóng lan ra ngoài 51dạng xem. Hiệu ứng sẽ được vẽ lên và được giới hạn bởi dạng xem mẹ gần nhất có nền 52không rỗng.</li> 53</ul> 54 55<p class="note"><strong>Lưu ý:</strong> <code>selectableItemBackgroundBorderless</code> là một thuộc tính 56mới được giới thiệu trong API mức 21.</p> 57 58 59<p>Hoặc, bạn có thể định nghĩa {@link android.graphics.drawable.RippleDrawable} 60làm tài nguyên XML bằng cách sử dụng phần tử <code>ripple</code>.</p> 61 62<p>Bạn có thể gán một màu cho các đối tượng {@link android.graphics.drawable.RippleDrawable}. Để thay đổi 63màu phản hồi chạm mặc định, hãy sử dụng thuộc tính <code>android:colorControlHighlight</code> 64của chủ đề.</p> 65 66<p>Để biết thêm thông tin, hãy xem tài liệu tham khảo API cho lớp {@link 67android.graphics.drawable.RippleDrawable}.</p> 68 69 70<h2 id="Reveal">Sử dụng Hiệu ứng Lộ ra</h2> 71 72<p>Hoạt hình lộ ra đảm bảo tính liên tục trực quan cho người dùng khi bạn hiện hoặc ẩn một nhóm phần tử 73UI. Phương thức {@link android.view.ViewAnimationUtils#createCircularReveal 74ViewAnimationUtils.createCircularReveal()} cho phép bạn tạo hiệu ứng hoạt hình một vòng tròn cắt hình 75để lộ ra hoặc ẩn một dạng xem.</p> 76 77<p>Để lộ ra một dạng xem ẩn trước đó bằng hiệu ứng này:</p> 78 79<pre> 80// previously invisible view 81View myView = findViewById(R.id.my_view); 82 83// get the center for the clipping circle 84int cx = (myView.getLeft() + myView.getRight()) / 2; 85int cy = (myView.getTop() + myView.getBottom()) / 2; 86 87// get the final radius for the clipping circle 88int finalRadius = Math.max(myView.getWidth(), myView.getHeight()); 89 90// create the animator for this view (the start radius is zero) 91Animator anim = 92 ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius); 93 94// make the view visible and start the animation 95myView.setVisibility(View.VISIBLE); 96anim.start(); 97</pre> 98 99<p>Để ẩn một dạng xem hiển thị trước đó bằng hiệu ứng này:</p> 100 101<pre> 102// previously visible view 103final View myView = findViewById(R.id.my_view); 104 105// get the center for the clipping circle 106int cx = (myView.getLeft() + myView.getRight()) / 2; 107int cy = (myView.getTop() + myView.getBottom()) / 2; 108 109// get the initial radius for the clipping circle 110int initialRadius = myView.getWidth(); 111 112// create the animation (the final radius is zero) 113Animator anim = 114 ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0); 115 116// make the view invisible when the animation is done 117anim.addListener(new AnimatorListenerAdapter() { 118 @Override 119 public void onAnimationEnd(Animator animation) { 120 super.onAnimationEnd(animation); 121 myView.setVisibility(View.INVISIBLE); 122 } 123}); 124 125// start the animation 126anim.start(); 127</pre> 128 129 130<h2 id="Transitions">Tùy chỉnh Chuyển tiếp Hoạt động</h2> 131 132<!-- shared transition video --> 133<div style="width:290px;margin-left:35px;float:right"> 134 <div class="framed-nexus5-port-span-5"> 135 <video class="play-on-hover" autoplay=""> 136 <source src="{@docRoot}design/material/videos/ContactsAnim.mp4"> 137 <source src="{@docRoot}design/material/videos/ContactsAnim.webm"> 138 <source src="{@docRoot}design/material/videos/ContactsAnim.ogv"> 139 </video> 140 </div> 141 <div style="font-size:10pt;margin-left:20px;margin-bottom:30px"> 142 <p class="img-caption" style="margin-top:3px;margin-bottom:10px"><strong>Hình 1</strong> - Chuyển tiếp 143 với những phần tử chung.</p> 144 <em>Để phát lại phim, nhấp vào màn hình thiết bị</em> 145 </div> 146</div> 147 148<p>Chuyển tiếp hoạt động trong các ứng dụng theo phong cách material design cung cấp kết nối trực quan giữa các trạng thái khác nhau 149thông qua chuyển động và chuyển đổi giữa những phần tử hay dùng. Bạn có thể quy định hoạt hình tùy chỉnh cho 150các chuyển tiếp ra vào và chuyển tiếp phần tử chung giữa các hoạt động.</p> 151 152<ul> 153<li>Chuyển tiếp <strong>vào</strong> xác định các dạng xem trong một hoạt động sẽ vào cảnh đó như thế nào. 154Ví dụ, trong chuyển tiếp vào dạng <em>nổ tung</em>, dạng xem sẽ vào cảnh từ bên ngoài 155và bay về phía chính giữa màn hình.</li> 156 157<li>Chuyển tiếp <strong>ra</strong> xác định các dạng xem trong một hoạt động sẽ ra khỏi cảnh như thế nào. Ví 158 dụ, trong chuyển tiếp ra kiểu <em>nổ tung</em>, dạng xem sẽ ra khỏi cảnh từ 159trung tâm.</li> 160 161<li>Chuyển tiếp <strong>phần tử chung</strong> xác định các dạng xem chung giữa hai hoạt động 162sẽ chuyển tiếp như thế nào giữa những hoạt động này. Ví dụ, nếu hai hoạt động có cùng 163hình ảnh ở các vị trí và kích cỡ khác nhau, chuyển tiếp phần tử chung <em>changeImageTransform</em> 164sẽ thể hiện và co giãn hình ảnh một cách mượt mà giữa những hoạt động này.</li> 165</ul> 166 167<p>Android 5.0 (API mức 21) hỗ trợ những chuyển tiếp ra vào sau:</p> 168 169<ul> 170<li><em>nổ tung</em> - Di chuyển các dạng xem vào hoặc ra khỏi chính giữa cảnh.</li> 171<li><em>trượt</em> - Di chuyển các dạng xem vào hoặc ra từ một trong các mép của cảnh.</li> 172<li><em>mờ dần</em> - Thêm hoặc gỡ bỏ dạng xem khỏi cảnh bằng cách thay đổi độ mờ đục của nó.</li> 173</ul> 174 175<p>Bất cứ chuyển tiếp nào mở rộng lớp {@link android.transition.Visibility} đều được hỗ trợ 176như một chuyển tiếp vào hoặc ra. Để biết thêm thông tin, hãy xem tài liệu tham khảo API cho lớp 177{@link android.transition.Transition}.</p> 178 179<p>Android 5.0 (API mức 21) cũng hỗ trợ những chuyển tiếp phần tử chung này:</p> 180 181<ul> 182<li><em>changeBounds</em> - Tạo hiệu ứng hoạt hình các thay đổi trong giới hạn bố trí của dạng xem mục tiêu.</li> 183<li><em>changeClipBounds</em> - Tạo hiệu ứng hoạt hình các thay đổi trong giới hạn cắt hình của dạng xem mục tiêu.</li> 184<li><em>changeTransform</em> - Tạo hiệu ứng hoạt hình các thay đổi về co giãn và xoay dạng xem mục tiêu.</li> 185<li><em>changeImageTransform</em> - Tạo hiệu ứng hoạt hình các thay đổi về kích cỡ và co giãn của ảnh mục tiêu.</li> 186</ul> 187 188<p>Khi bạn cho phép chuyển tiếp hoạt động trong ứng dụng của mình, chuyển tiếp mờ dần chéo cross-fading 189mặc định sẽ được kích hoạt giữa các hoạt động ra vào.</p> 190 191<img src="{@docRoot}training/material/images/SceneTransition.png" alt="" width="600" height="405" style="margin-top:20px" /> 192<p class="img-caption"> 193 <strong>Hình 2</strong> - Chuyển tiếp cảnh với một phần tử chung. 194</p> 195 196<h3>Quy định chuyển tiếp tùy chỉnh</h3> 197 198<p>Trước tiên, cho phép chuyển tiếp nội dung cửa sổ bằng thuộc tính <code>android:windowContentTransitions</code> 199khi bạn định nghĩa một kiểu kế thừa từ chủ đề material. Bạn cũng có thể quy định chuyển tiếp 200ra, vào và phần tử chung trong định nghĩa kiểu của mình:</p> 201 202<pre> 203<style name="BaseAppTheme" parent="android:Theme.Material"> 204 <!-- enable window content transitions --> 205 <item name="android:windowContentTransitions">true</item> 206 207 <!-- specify enter and exit transitions --> 208 <item name="android:windowEnterTransition">@transition/explode</item> 209 <item name="android:windowExitTransition">@transition/explode</item> 210 211 <!-- specify shared element transitions --> 212 <item name="android:windowSharedElementEnterTransition"> 213 @transition/change_image_transform</item> 214 <item name="android:windowSharedElementExitTransition"> 215 @transition/change_image_transform</item> 216</style> 217</pre> 218 219<p>Chuyển tiếp <code>change_image_transform</code> trong ví dụ này được định nghĩa như sau:</p> 220 221<pre> 222<!-- res/transition/change_image_transform.xml --> 223<!-- (see also Shared Transitions below) --> 224<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"> 225 <changeImageTransform/> 226</transitionSet> 227</pre> 228 229<p>Phần tử <code>changeImageTransform</code> tương ứng với lớp 230{@link android.transition.ChangeImageTransform}. Để biết thêm thông tin, hãy xem tài liệu tham khảo API 231cho {@link android.transition.Transition}.</p> 232 233<p>Thay vào đó, để cho phép chuyển tiếp nội dung cửa sổ trong mã của bạn, hãy gọi phương thức 234{@link android.view.Window#requestFeature Window.requestFeature()}:</p> 235 236<pre> 237// inside your activity (if you did not enable transitions in your theme) 238getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); 239 240// set an exit transition 241getWindow().setExitTransition(new Explode()); 242</pre> 243 244<p>Để quy định chuyển tiếp trong mã của bạn, hãy gọi những phương thức này bằng đối tượng {@link 245android.transition.Transition}:</p> 246 247<ul> 248 <li>{@link android.view.Window#setEnterTransition Window.setEnterTransition()}</li> 249 <li>{@link android.view.Window#setExitTransition Window.setExitTransition()}</li> 250 <li>{@link android.view.Window#setSharedElementEnterTransition 251 Window.setSharedElementEnterTransition()}</li> 252 <li>{@link android.view.Window#setSharedElementExitTransition 253 Window.setSharedElementExitTransition()}</li> 254</ul> 255 256<p>Phương thức {@link android.view.Window#setExitTransition setExitTransition()} và {@link 257android.view.Window#setSharedElementExitTransition setSharedElementExitTransition()} định nghĩa 258chuyển tiếp ra cho hoạt động gọi. Phương thức {@link android.view.Window#setEnterTransition 259setEnterTransition()} và {@link android.view.Window#setSharedElementEnterTransition 260setSharedElementEnterTransition()} định nghĩa chuyển tiếp vào cho hoạt động được gọi.</p> 261 262<p>Để có đầy đủ hiệu ứng của một chuyển tiếp, bạn phải cho phép chuyển tiếp nội dung cửa sổ trên cả hoạt động 263gọi và được gọi. Nếu không, hoạt động gọi sẽ bắt đầu chuyển tiếp ra, 264nhưng khi đó bạn sẽ thấy chuyển tiếp cửa sổ (như co giãn và mờ dần).</p> 265 266<p>Để bắt đầu một chuyển tiếp vào ngay khi có thể, hãy sử dụng phương thức 267{@link android.view.Window#setAllowEnterTransitionOverlap Window.setAllowEnterTransitionOverlap()} 268trên hoạt động được gọi. Nó cho phép bạn có chuyển tiếp vào ấn tượng hơn.</p> 269 270<h3>Bắt đầu một hoạt động bằng chuyển tiếp</h3> 271 272<p>Nếu bạn cho phép chuyển tiếp và đặt chuyển tiếp ra cho một hoạt động, chuyển tiếp sẽ được 273kích hoạt khi bạn khởi chạy một hoạt động khác như sau:</p> 274 275<pre> 276startActivity(intent, 277 ActivityOptions.makeSceneTransitionAnimation(this).toBundle()); 278</pre> 279 280<p>Nếu bạn đặt một chuyển tiếp vào cho hoạt động thứ hai, chuyển tiếp này cũng được kích hoạt khi hoạt động 281bắt đầu. Để vô hiệu hoá chuyển tiếp khi bạn bắt đầu một hoạt động khác, hãy cung cấp 282một nhóm tùy chọn <code>null</code>.</p> 283 284<h3>Bắt đầu một hoạt động bằng một phần tử chung</h3> 285 286<p>Để tạo một hoạt hình chuyển tiếp màn hình giữa hai hoạt động có một phần tử chung:</p> 287 288<ol> 289<li>Cho phép chuyển tiếp nội dung cửa sổ trong chủ đề của bạn.</li> 290<li>Quy định một chuyển tiếp phần tử chung trong kiểu của bạn.</li> 291<li>Định nghĩa chuyển tiếp của bạn dưới dạng một tài nguyên XML.</li> 292<li>Gán một tên chung cho các phần tử chung ở cả hai bố trí bằng thuộc tính 293 <code>android:transitionName</code>.</li> 294<li>Sử dụng phương thức {@link android.app.ActivityOptions#makeSceneTransitionAnimation 295ActivityOptions.makeSceneTransitionAnimation()}.</li> 296</ol> 297 298<pre> 299// get the element that receives the click event 300final View imgContainerView = findViewById(R.id.img_container); 301 302// get the common element for the transition in this activity 303final View androidRobotView = findViewById(R.id.image_small); 304 305// define a click listener 306imgContainerView.setOnClickListener(new View.OnClickListener() { 307 @Override 308 public void onClick(View view) { 309 Intent intent = new Intent(this, Activity2.class); 310 // create the transition animation - the images in the layouts 311 // of both activities are defined with android:transitionName="robot" 312 ActivityOptions options = ActivityOptions 313 .makeSceneTransitionAnimation(this, androidRobotView, "robot"); 314 // start the new activity 315 startActivity(intent, options.toBundle()); 316 } 317}); 318</pre> 319 320<p>Đối với các dạng xem động dùng chung mà bạn khởi tạo trong mã của mình, hãy sử dụng phương thức 321{@link android.view.View#setTransitionName View.setTransitionName()} để quy định một 322tên phần tử chung trong cả hai hoạt động.</p> 323 324<p>Để đảo ngược hoạt hình chuyển tiếp cảnh khi bạn kết thúc hoạt động thứ hai, hãy gọi phương thức 325{@link android.app.Activity#finishAfterTransition Activity.finishAfterTransition()} 326thay vì {@link android.app.Activity#finish Activity.finish()}.</p> 327 328<h3>Bắt đầu một hoạt động bằng nhiều phần tử chung</h3> 329 330<p>Để tạo một hoạt hình chuyển tiếp cảnh giữa hai hoạt động có nhiều hơn một phần tử 331chung, hãy định nghĩa các phần tử chung trong cả hai bố trí bằng thuộc tính <code>android:transitionName</code> 332 (hoặc sử dụng phương thức {@link android.view.View#setTransitionName View.setTransitionName()} 333trong cả hai hoạt động), và tạo một đối tượng {@link android.app.ActivityOptions} như sau:</p> 334 335<pre> 336ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, 337 Pair.create(view1, "agreedName1"), 338 Pair.create(view2, "agreedName2")); 339</pre> 340 341 342<h2 id="CurvedMotion">Sử dụng Chuyển động Cong</h2> 343 344<p>Hoạt hình theo phong cách material design phụ thuộc vào đường cong làm mẫu hình nội suy thời gian 345và chuyển động không gian. Với Android 5.0 (API mức 21) trở lên, bạn có thể định nghĩa đường cong định thời tùy chỉnh và 346mẫu hình chuyển động cong cho hoạt hình.</p> 347 348<p>Lớp {@link android.view.animation.PathInterpolator} là một hàm nội suy mới dựa trên đường cong 349Bézier hoặc đối tượng {@link android.graphics.Path}. Hàm nội suy này quy định một đường cong chuyển động 350trong một hình vuông 1x1, với các điểm neo tại (0,0) và (1,1) cùng các điểm kiểm soát được quy định bằng cách sử dụng 351các tham đối của hàm dựng. Bạn cũng có thể định nghĩa một hàm nội suy đường dẫn dưới dạng tài nguyên XML:</p> 352 353<pre> 354<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" 355 android:controlX1="0.4" 356 android:controlY1="0" 357 android:controlX2="1" 358 android:controlY2="1"/> 359</pre> 360 361<p>Hệ thống cung cấp tài nguyên XML cho ba đường cong cơ bản trong đặc tả 362material design:</p> 363 364<ul> 365 <li><code>@interpolator/fast_out_linear_in.xml</code></li> 366 <li><code>@interpolator/fast_out_slow_in.xml</code></li> 367 <li><code>@interpolator/linear_out_slow_in.xml</code></li> 368</ul> 369 370<p>Bạn có thể chuyển một đối tượng {@link android.view.animation.PathInterpolator} tới phương thức {@link 371android.animation.Animator#setInterpolator Animator.setInterpolator()}.</p> 372 373<p>Lớp {@link android.animation.ObjectAnimator} có các hàm dựng mới cho phép bạn tạo hiệu ứng hoạt hình 374cho các tọa độ dọc theo một đường dẫn bằng hai hoặc nhiều thuộc tính đồng thời. Ví dụ, trình tạo hoạt hình sau 375sử dụng một đối tượng {@link android.graphics.Path} để tạo hiệu ứng hoạt hình cho thuộc tính X và Y của một dạng xem:</p> 376 377<pre> 378ObjectAnimator mAnimator; 379mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path); 380... 381mAnimator.start(); 382</pre> 383 384 385<h2 id="ViewState">Tạo Hiệu ứng Hoạt hình Thay đổi Trạng thái Xem</h2> 386 387<p>Lớp {@link android.animation.StateListAnimator} cho phép bạn định nghĩa trình tạo hoạt hình để chạy khi 388trạng thái của dạng xem thay đổi. Ví dụ sau cho biết cách định nghĩa một {@link 389android.animation.StateListAnimator} dưới dạng tài nguyên XML:</p> 390 391<pre> 392<!-- animate the translationZ property of a view when pressed --> 393<selector xmlns:android="http://schemas.android.com/apk/res/android"> 394 <item android:state_pressed="true"> 395 <set> 396 <objectAnimator android:propertyName="translationZ" 397 android:duration="@android:integer/config_shortAnimTime" 398 android:valueTo="2dp" 399 android:valueType="floatType"/> 400 <!-- you could have other objectAnimator elements 401 here for "x" and "y", or other properties --> 402 </set> 403 </item> 404 <item android:state_enabled="true" 405 android:state_pressed="false" 406 android:state_focused="true"> 407 <set> 408 <objectAnimator android:propertyName="translationZ" 409 android:duration="100" 410 android:valueTo="0" 411 android:valueType="floatType"/> 412 </set> 413 </item> 414</selector> 415</pre> 416 417<p>Để gắn kèm hoạt hình trạng thái dạng xem tùy chỉnh vào một dạng xem, hãy định nghĩa một trình tạo hoạt hình bằng cách sử dụng phần tử 418<code>selector</code> trong một tệp tài nguyên XML như trong ví dụ này, và gán nó cho dạng xem 419của bạn bằng thuộc tính <code>android:stateListAnimator</code>. Để gán một trình tạo hoạt hình danh sách trạng thái 420cho một dạng xem trong mã của bạn, hãy sử dụng phương thức {@link android.animation.AnimatorInflater#loadStateListAnimator 421AnimationInflater.loadStateListAnimator()} và gán trình tạo hoạt hình cho dạng xem của bạn bằng phương thức 422{@link android.view.View#setStateListAnimator View.setStateListAnimator()}.</p> 423 424<p>Khi chủ đề của bạn mở rộng ra chủ đề material, các nút sẽ có hoạt hình Z theo mặc định. Để tránh hành vi 425này trong nút của bạn, hãy đặt thuộc tính <code>android:stateListAnimator</code> thành 426<code>@null</code>.</p> 427 428<p>Lớp {@link android.graphics.drawable.AnimatedStateListDrawable} cho phép bạn tạo các nội dung vẽ được 429để hiển thị hoạt hình giữa các thay đổi trạng thái của dạng xem được liên kết. Một số widget hệ thống trong 430Android 5.0 sử dụng những hoạt hình này theo mặc định. Ví dụ sau cho biết cách 431cách định nghĩa {@link android.graphics.drawable.AnimatedStateListDrawable} dưới dạng tài nguyên XML:</p> 432 433<pre> 434<!-- res/drawable/myanimstatedrawable.xml --> 435<animated-selector 436 xmlns:android="http://schemas.android.com/apk/res/android"> 437 438 <!-- provide a different drawable for each state--> 439 <item android:id="@+id/pressed" android:drawable="@drawable/drawableP" 440 android:state_pressed="true"/> 441 <item android:id="@+id/focused" android:drawable="@drawable/drawableF" 442 android:state_focused="true"/> 443 <item android:id="@id/default" 444 android:drawable="@drawable/drawableD"/> 445 446 <!-- specify a transition --> 447 <transition android:fromId="@+id/default" android:toId="@+id/pressed"> 448 <animation-list> 449 <item android:duration="15" android:drawable="@drawable/dt1"/> 450 <item android:duration="15" android:drawable="@drawable/dt2"/> 451 ... 452 </animation-list> 453 </transition> 454 ... 455</animated-selector> 456</pre> 457 458 459<h2 id="AnimVector">Tạo Hiệu ứng Hoạt hình Nội dung vẽ được Véc-tơ</h2> 460 461<p><a href="{@docRoot}training/material/drawables.html#VectorDrawables">Nội dung vẽ được Véc-tơ</a> sẽ co giãn được 462mà không làm mất độ sắc nét. Lớp {@link android.graphics.drawable.AnimatedVectorDrawable} 463cho phép bạn tạo hiệu ứng hoạt hình các thuộc tính của nội dung vẽ được véc-tơ.</p> 464 465<p>Thường thì bạn định nghĩa nội dung vẽ được véc-tơ hoạt hình theo ba tệp XML:</p> 466 467<ul> 468<li>Nội dung vẽ được véc-tơ với phần tử <code><vector></code> trong 469<code>res/drawable/</code></li> 470<li>Nội dung vẽ được véc-tơ hoạt hình với phần tử <code><animated-vector></code> trong 471<code>res/drawable/</code></li> 472<li>Một hoặc nhiều trình tạo hoạt hình đối tượng với phần tử <code><objectAnimator></code> trong 473<code>res/anim/</code></li> 474</ul> 475 476<p>Nội dung vẽ được véc-tơ hoạt hình có thể tạo hiệu ứng hoạt hình các thuộc tính của phần tử <code><group></code> và 477<code><path></code>. Phần tử <code><group></code> định nghĩa một bộ 478đường dẫn hoặc nhóm phụ và phần tử <code><path></code> định nghĩa các đường dẫn sẽ được vẽ.</p> 479 480<p>Khi định nghĩa một nội dung vẽ được véc-tơ mà bạn muốn tạo hiệu ứng hoạt hình, hãy sử dụng thuộc tính <code>android:name</code> 481để gán một tên duy nhất cho các nhóm và đường dẫn, sao cho bạn có thể tham chiếu tới chúng từ các định nghĩa 482trình tạo hoạt hình của mình. Ví dụ:</p> 483 484<pre> 485<!-- res/drawable/vectordrawable.xml --> 486<vector xmlns:android="http://schemas.android.com/apk/res/android" 487 android:height="64dp" 488 android:width="64dp" 489 android:viewportHeight="600" 490 android:viewportWidth="600"> 491 <group 492 <strong>android:name="rotationGroup"</strong> 493 android:pivotX="300.0" 494 android:pivotY="300.0" 495 android:rotation="45.0" > 496 <path 497 <strong>android:name="v"</strong> 498 android:fillColor="#000000" 499 android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" /> 500 </group> 501</vector> 502</pre> 503 504<p>Định nghĩa nội dung vẽ được véc-tơ hoạt hình sẽ tham chiếu tới các nhóm và đường dẫn trong nội dung vẽ được véc-tơ theo 505tên của chúng:</p> 506 507<pre> 508<!-- res/drawable/animvectordrawable.xml --> 509<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" 510 android:drawable="@drawable/vectordrawable" > 511 <target 512 android:name="rotationGroup" 513 android:animation="@anim/rotation" /> 514 <target 515 android:name="v" 516 android:animation="@anim/path_morph" /> 517</animated-vector> 518</pre> 519 520<p>Định nghĩa hoạt hình biểu diễn các đối tượng {@link android.animation.ObjectAnimator} hoặc {@link 521android.animation.AnimatorSet}. Trình tạo hoạt hình đầu tiên trong ví dụ này sẽ xoay nhóm 522đối tượng 360 độ:</p> 523 524<pre> 525<!-- res/anim/rotation.xml --> 526<objectAnimator 527 android:duration="6000" 528 android:propertyName="rotation" 529 android:valueFrom="0" 530 android:valueTo="360" /> 531</pre> 532 533<p>Trình tạo hoạt hình thứ hai trong ví dụ này sẽ đổi dạng đường dẫn của nội dung vẽ được véc-tơ từ hình này sang 534hình khác. Cả hai đường dẫn đều phải tương thích với việc đổi dạng: chúng phải có cùng số lệnh 535và cùng số lượng tham số cho từng lệnh.</p> 536 537<pre> 538<!-- res/anim/path_morph.xml --> 539<set xmlns:android="http://schemas.android.com/apk/res/android"> 540 <objectAnimator 541 android:duration="3000" 542 android:propertyName="pathData" 543 android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z" 544 android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z" 545 android:valueType="pathType" /> 546</set> 547</pre> 548 549<p>Để biết thêm thông tin, hãy xem tài liệu tham khảo API cho {@link 550android.graphics.drawable.AnimatedVectorDrawable}.</p> 551