Trong bài viết này, tôi sẽ nói về compound view trong Android.
- What is a compound view?
- What are the advantages of using it?
- How to write one?
Tôi sẽ trả lời câu hỏi này bằng cách viết một compound view đơn giản hiển thị xếp hạng từ các mạng xã hội.
What is a compound view ?
Compound view về cơ bản là một ViewGround có các hành động được xác định trước và một tập hợp các View bên trong nó. Trong ví dụ này, compound view là một LinearLayout cùng với 3 TextView bên trong, animation và hiệu ứng fadeIn.
What are the advantages of a compound view?
- Đóng gói và tập trung xử lý logic.
- Tránh code duplicate.
- Dễ dàng maintain và modify trong tương lai.
Writing a compound view
Hãy tưởng tượng ứng dụng của mình hiển thị các số điểm ưa thích của ứng dụng và những POI đó có các rating được liên kết từ nhiều nguồn khác nhau, bạn sẽ hiển thị rating ở nhiều nơi, POI có thể có xếp hạng Facebook nhưng không phải là Foursquare và trong tương lai chúng ta có thể có nguồn xếp hạng mới.
Sử dụng compound view, Tôi có thể gói gọn tất cả logic này và có thể dễ dàng thay đổi nó trong tương lai nếu cần thiết.
XML Layout
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | <span class="token operator"><</span>merge xmlns<span class="token operator">:</span>android<span class="token operator">=</span><span class="token string">"http://schemas.android.com/apk/res/android"</span> android<span class="token operator">:</span>orientation<span class="token operator">=</span><span class="token string">"horizontal"</span> android<span class="token operator">:</span>layout_width<span class="token operator">=</span><span class="token string">"wrap_content"</span> android<span class="token operator">:</span>layout_height<span class="token operator">=</span><span class="token string">"wrap_content"</span><span class="token operator">></span> <span class="token operator"><</span>TextView android<span class="token operator">:</span>id<span class="token operator">=</span><span class="token string">"@+id/facebookTv"</span> android<span class="token operator">:</span>textColor<span class="token operator">=</span><span class="token string">"@android:color/black"</span> android<span class="token operator">:</span>textSize<span class="token operator">=</span><span class="token string">"16sp"</span> android<span class="token operator">:</span>drawableStart<span class="token operator">=</span><span class="token string">"@drawable/ic_facebook"</span> android<span class="token operator">:</span>drawableLeft<span class="token operator">=</span><span class="token string">"@drawable/ic_facebook"</span> android<span class="token operator">:</span>drawablePadding<span class="token operator">=</span><span class="token string">"4dp"</span> android<span class="token operator">:</span>gravity<span class="token operator">=</span><span class="token string">"center_vertical"</span> android<span class="token operator">:</span>layout_width<span class="token operator">=</span><span class="token string">"wrap_content"</span> android<span class="token operator">:</span>layout_height<span class="token operator">=</span><span class="token string">"wrap_content"</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span>TextView android<span class="token operator">:</span>id<span class="token operator">=</span><span class="token string">"@+id/yelpTv"</span> android<span class="token operator">:</span>textColor<span class="token operator">=</span><span class="token string">"@android:color/black"</span> android<span class="token operator">:</span>textSize<span class="token operator">=</span><span class="token string">"16sp"</span> android<span class="token operator">:</span>drawableStart<span class="token operator">=</span><span class="token string">"@drawable/ic_yelp"</span> android<span class="token operator">:</span>drawableLeft<span class="token operator">=</span><span class="token string">"@drawable/ic_yelp"</span> android<span class="token operator">:</span>drawablePadding<span class="token operator">=</span><span class="token string">"4dp"</span> android<span class="token operator">:</span>gravity<span class="token operator">=</span><span class="token string">"center_vertical"</span> android<span class="token operator">:</span>layout_centerVertical<span class="token operator">=</span><span class="token string">"true"</span> android<span class="token operator">:</span>layout_marginStart<span class="token operator">=</span><span class="token string">"12dp"</span> android<span class="token operator">:</span>layout_marginLeft<span class="token operator">=</span><span class="token string">"12dp"</span> android<span class="token operator">:</span>layout_width<span class="token operator">=</span><span class="token string">"wrap_content"</span> android<span class="token operator">:</span>layout_height<span class="token operator">=</span><span class="token string">"wrap_content"</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span>TextView android<span class="token operator">:</span>id<span class="token operator">=</span><span class="token string">"@+id/foursquareTv"</span> android<span class="token operator">:</span>textColor<span class="token operator">=</span><span class="token string">"@android:color/black"</span> android<span class="token operator">:</span>textSize<span class="token operator">=</span><span class="token string">"16sp"</span> android<span class="token operator">:</span>drawableStart<span class="token operator">=</span><span class="token string">"@drawable/ic_foursquare"</span> android<span class="token operator">:</span>drawableLeft<span class="token operator">=</span><span class="token string">"@drawable/ic_foursquare"</span> android<span class="token operator">:</span>layout_centerVertical<span class="token operator">=</span><span class="token string">"true"</span> android<span class="token operator">:</span>gravity<span class="token operator">=</span><span class="token string">"center_vertical"</span> android<span class="token operator">:</span>drawablePadding<span class="token operator">=</span><span class="token string">"4dp"</span> android<span class="token operator">:</span>layout_marginStart<span class="token operator">=</span><span class="token string">"12dp"</span> android<span class="token operator">:</span>layout_marginLeft<span class="token operator">=</span><span class="token string">"12dp"</span> android<span class="token operator">:</span>layout_width<span class="token operator">=</span><span class="token string">"wrap_content"</span> android<span class="token operator">:</span>layout_height<span class="token operator">=</span><span class="token string">"wrap_content"</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>merge<span class="token operator">></span> |
Đây là file XML layout tôi đang sử dụng để inflate vào LinearLayout, chú ý merge Đây là một thành phần quan trọng, thẻ merge là một cách để tránh ViewGroup dư thừa, nói cách khác, nếu chúng ta inflate này vào LinearLayout, chúng ta sẽ không nên sử dụng LinearLayout parent trong XML, nếu không cuối cùng chúng ta sẽ có 2 LinearLayout, 1 trong số đó không cần thiết.
Không dùng merge
- LinearLayout -> LinearLayout -> 3 TextViews
Sử dụng merge
- LinearLayout -> 3 TextViews
RatingsView
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">RatingsView</span> <span class="token keyword">extends</span> <span class="token class-name">LinearLayout</span> <span class="token punctuation">{</span> <span class="token comment">//Text views</span> <span class="token keyword">private</span> TextView mFacebookTv<span class="token punctuation">,</span>mYelpTv<span class="token punctuation">,</span>mFoursquareTv<span class="token punctuation">;</span> <span class="token keyword">private</span> POI mPOI<span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token function">RatingsView</span><span class="token punctuation">(</span>Context context<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span>null<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token function">RatingsView</span><span class="token punctuation">(</span>Context context<span class="token punctuation">,</span> AttributeSet attrs<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> attrs<span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token function">RatingsView</span><span class="token punctuation">(</span>Context context<span class="token punctuation">,</span> AttributeSet attrs<span class="token punctuation">,</span> <span class="token keyword">int</span> defStyleAttr<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> attrs<span class="token punctuation">,</span> defStyleAttr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@TargetApi</span><span class="token punctuation">(</span>Build<span class="token punctuation">.</span>VERSION_CODES<span class="token punctuation">.</span>LOLLIPOP<span class="token punctuation">)</span> <span class="token keyword">public</span> <span class="token function">RatingsView</span><span class="token punctuation">(</span>Context context<span class="token punctuation">,</span> AttributeSet attrs<span class="token punctuation">,</span> <span class="token keyword">int</span> defStyleAttr<span class="token punctuation">,</span> <span class="token keyword">int</span> defStyleRes<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> attrs<span class="token punctuation">,</span> defStyleAttr<span class="token punctuation">,</span> defStyleRes<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Initialize view */</span> <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">//Inflate xml resource, pass "this" as the parent, we use <merge> tag in xml to avoid</span> <span class="token comment">//redundant parent, otherwise a LinearLayout will be added to this LinearLayout ending up</span> <span class="token comment">//with two view groups</span> <span class="token function">inflate</span><span class="token punctuation">(</span><span class="token function">getContext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>R<span class="token punctuation">.</span>layout<span class="token punctuation">.</span>ratings_layout<span class="token punctuation">,</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//Get references to text views</span> mFacebookTv <span class="token operator">=</span> <span class="token punctuation">(</span>TextView<span class="token punctuation">)</span><span class="token function">findViewById</span><span class="token punctuation">(</span>R<span class="token punctuation">.</span>id<span class="token punctuation">.</span>facebookTv<span class="token punctuation">)</span><span class="token punctuation">;</span> mYelpTv <span class="token operator">=</span> <span class="token punctuation">(</span>TextView<span class="token punctuation">)</span><span class="token function">findViewById</span><span class="token punctuation">(</span>R<span class="token punctuation">.</span>id<span class="token punctuation">.</span>yelpTv<span class="token punctuation">)</span><span class="token punctuation">;</span> mFoursquareTv <span class="token operator">=</span> <span class="token punctuation">(</span>TextView<span class="token punctuation">)</span><span class="token function">findViewById</span><span class="token punctuation">(</span>R<span class="token punctuation">.</span>id<span class="token punctuation">.</span>foursquareTv<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//Initially all views are gone</span> mFacebookTv<span class="token punctuation">.</span><span class="token function">setVisibility</span><span class="token punctuation">(</span>GONE<span class="token punctuation">)</span><span class="token punctuation">;</span> mYelpTv<span class="token punctuation">.</span><span class="token function">setVisibility</span><span class="token punctuation">(</span>GONE<span class="token punctuation">)</span><span class="token punctuation">;</span> mFoursquareTv<span class="token punctuation">.</span><span class="token function">setVisibility</span><span class="token punctuation">(</span>GONE<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//Reset alpha</span> mFacebookTv<span class="token punctuation">.</span><span class="token function">setAlpha</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> mYelpTv<span class="token punctuation">.</span><span class="token function">setAlpha</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> mFoursquareTv<span class="token punctuation">.</span><span class="token function">setAlpha</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//Animate views with a nice fadeIn effect before drawing</span> <span class="token function">getViewTreeObserver</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addOnPreDrawListener</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">ViewTreeObserver<span class="token punctuation">.</span>OnPreDrawListener</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">onPreDraw</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">getViewTreeObserver</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">removeOnPreDrawListener</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span>mPOI<span class="token punctuation">.</span><span class="token function">hasFacebookRating</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> ViewCompat<span class="token punctuation">.</span><span class="token function">animate</span><span class="token punctuation">(</span>mFacebookTv<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">alpha</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setDuration</span><span class="token punctuation">(</span><span class="token number">500</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span>mPOI<span class="token punctuation">.</span><span class="token function">hasYelpRating</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> ViewCompat<span class="token punctuation">.</span><span class="token function">animate</span><span class="token punctuation">(</span>mYelpTv<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">alpha</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setStartDelay</span><span class="token punctuation">(</span><span class="token number">120</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setDuration</span><span class="token punctuation">(</span><span class="token number">500</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span>mPOI<span class="token punctuation">.</span><span class="token function">hasFoursquareRating</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> ViewCompat<span class="token punctuation">.</span><span class="token function">animate</span><span class="token punctuation">(</span>mFoursquareTv<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">alpha</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setStartDelay</span><span class="token punctuation">(</span><span class="token number">240</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setDuration</span><span class="token punctuation">(</span><span class="token number">500</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setPOI</span><span class="token punctuation">(</span>POI poi<span class="token punctuation">)</span> <span class="token punctuation">{</span> mPOI <span class="token operator">=</span> poi<span class="token punctuation">;</span> <span class="token function">setupView</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//This method is called to show the ratings</span> <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">setupView</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span>mPOI<span class="token punctuation">.</span><span class="token function">hasFacebookRating</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span> mFacebookTv<span class="token punctuation">.</span><span class="token function">setVisibility</span><span class="token punctuation">(</span>VISIBLE<span class="token punctuation">)</span><span class="token punctuation">;</span> mFacebookTv<span class="token punctuation">.</span><span class="token function">setText</span><span class="token punctuation">(</span>String<span class="token punctuation">.</span><span class="token function">valueOf</span><span class="token punctuation">(</span>mPOI<span class="token punctuation">.</span><span class="token function">getFacebookRating</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span><span class="token punctuation">(</span>mPOI<span class="token punctuation">.</span><span class="token function">hasFoursquareRating</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> mFoursquareTv<span class="token punctuation">.</span><span class="token function">setVisibility</span><span class="token punctuation">(</span>VISIBLE<span class="token punctuation">)</span><span class="token punctuation">;</span> mFoursquareTv<span class="token punctuation">.</span><span class="token function">setText</span><span class="token punctuation">(</span>String<span class="token punctuation">.</span><span class="token function">valueOf</span><span class="token punctuation">(</span>mPOI<span class="token punctuation">.</span><span class="token function">getFoursquareRating</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span><span class="token punctuation">(</span>mPOI<span class="token punctuation">.</span><span class="token function">hasYelpRating</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span> mYelpTv<span class="token punctuation">.</span><span class="token function">setVisibility</span><span class="token punctuation">(</span>VISIBLE<span class="token punctuation">)</span><span class="token punctuation">;</span> mYelpTv<span class="token punctuation">.</span><span class="token function">setText</span><span class="token punctuation">(</span>String<span class="token punctuation">.</span><span class="token function">valueOf</span><span class="token punctuation">(</span>mPOI<span class="token punctuation">.</span><span class="token function">getYelpRating</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Method init() là nơi logic xảy ra, chúng inflate vào XML layout và truyền “this” vào parameter thứ 3, các View inflate sẽ được thêm vào như là children của LinearLayout. Sau đó, tôi set visibility cho views là gone và thêm animation đơn giản fadeIn.
setPOI() nhận một đối tượng POI và thiết lập chế độ xem để hiện thị xếp hạng khả dụng cho POI đó. Và điều đó, tôi biết có một compound view mà tôi có thể sử dụng ở mọi nơi trong ứng dụng của mình.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MainActivity</span> <span class="token keyword">extends</span> <span class="token class-name">AppCompatActivity</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">protected</span> <span class="token keyword">void</span> <span class="token function">onCreate</span><span class="token punctuation">(</span>Bundle savedInstanceState<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">onCreate</span><span class="token punctuation">(</span>savedInstanceState<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setContentView</span><span class="token punctuation">(</span>R<span class="token punctuation">.</span>layout<span class="token punctuation">.</span>activity_main<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//Get rating view</span> RatingsView ratingsView <span class="token operator">=</span> <span class="token punctuation">(</span>RatingsView<span class="token punctuation">)</span><span class="token function">findViewById</span><span class="token punctuation">(</span>R<span class="token punctuation">.</span>id<span class="token punctuation">.</span>ratingsView<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//Create a dummy POI with some values for ratings</span> POI poi <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">POI</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> poi<span class="token punctuation">.</span><span class="token function">setFacebookRating</span><span class="token punctuation">(</span><span class="token number">8.8f</span><span class="token punctuation">)</span><span class="token punctuation">;</span> poi<span class="token punctuation">.</span><span class="token function">setYelpRating</span><span class="token punctuation">(</span><span class="token number">7f</span><span class="token punctuation">)</span><span class="token punctuation">;</span> poi<span class="token punctuation">.</span><span class="token function">setFoursquareRating</span><span class="token punctuation">(</span><span class="token number">6.3f</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//Pass the POI to rating view</span> ratingsView<span class="token punctuation">.</span><span class="token function">setPOI</span><span class="token punctuation">(</span>poi<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token operator"><</span>RelativeLayout xmlns<span class="token operator">:</span>android<span class="token operator">=</span><span class="token string">"http://schemas.android.com/apk/res/android"</span> xmlns<span class="token operator">:</span>tools<span class="token operator">=</span><span class="token string">"http://schemas.android.com/tools"</span> android<span class="token operator">:</span>layout_width<span class="token operator">=</span><span class="token string">"match_parent"</span> android<span class="token operator">:</span>layout_height<span class="token operator">=</span><span class="token string">"match_parent"</span> android<span class="token operator">:</span>paddingLeft<span class="token operator">=</span><span class="token string">"@dimen/activity_horizontal_margin"</span> android<span class="token operator">:</span>paddingRight<span class="token operator">=</span><span class="token string">"@dimen/activity_horizontal_margin"</span> android<span class="token operator">:</span>paddingTop<span class="token operator">=</span><span class="token string">"@dimen/activity_vertical_margin"</span> android<span class="token operator">:</span>paddingBottom<span class="token operator">=</span><span class="token string">"@dimen/activity_vertical_margin"</span> tools<span class="token operator">:</span>context<span class="token operator">=</span><span class="token string">".MainActivity"</span><span class="token operator">></span> <span class="token operator"><</span>sserra<span class="token punctuation">.</span>compoundview<span class="token punctuation">.</span>RatingsView android<span class="token operator">:</span>id<span class="token operator">=</span><span class="token string">"@+id/ratingsView"</span> android<span class="token operator">:</span>layout_centerInParent<span class="token operator">=</span><span class="token string">"true"</span> android<span class="token operator">:</span>layout_width<span class="token operator">=</span><span class="token string">"wrap_content"</span> android<span class="token operator">:</span>layout_height<span class="token operator">=</span><span class="token string">"wrap_content"</span><span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>RelativeLayout<span class="token operator">></span> |
Bạn có thể thấy rằng điều này tránh duplicate logic mỗi lần tôi muốn hiển thị rating, nếu tôi cần thêm rating mới, tôi chỉ cần thay đổi nó trong class RatingsView để tránh code duplicate.
Tài liệu tham khảo
https://medium.com/@Sserra90/android-writing-a-compound-view-1eacbf1957fc