1079d02b6021c640213888d446434e2c925756e29Jin Cao/* 2079d02b6021c640213888d446434e2c925756e29Jin Cao * Copyright (C) 2014 The Android Open Source Project 3079d02b6021c640213888d446434e2c925756e29Jin Cao * 4079d02b6021c640213888d446434e2c925756e29Jin Cao * Licensed under the Apache License, Version 2.0 (the "License"); 5079d02b6021c640213888d446434e2c925756e29Jin Cao * you may not use this file except in compliance with the License. 6079d02b6021c640213888d446434e2c925756e29Jin Cao * You may obtain a copy of the License at 7079d02b6021c640213888d446434e2c925756e29Jin Cao * 8079d02b6021c640213888d446434e2c925756e29Jin Cao * http://www.apache.org/licenses/LICENSE-2.0 9079d02b6021c640213888d446434e2c925756e29Jin Cao * 10079d02b6021c640213888d446434e2c925756e29Jin Cao * Unless required by applicable law or agreed to in writing, software 11079d02b6021c640213888d446434e2c925756e29Jin Cao * distributed under the License is distributed on an "AS IS" BASIS, 12079d02b6021c640213888d446434e2c925756e29Jin Cao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13079d02b6021c640213888d446434e2c925756e29Jin Cao * See the License for the specific language governing permissions and 14079d02b6021c640213888d446434e2c925756e29Jin Cao * limitations under the License. 15079d02b6021c640213888d446434e2c925756e29Jin Cao */ 16079d02b6021c640213888d446434e2c925756e29Jin Cao 17079d02b6021c640213888d446434e2c925756e29Jin Caopackage com.android.mail.ui; 18079d02b6021c640213888d446434e2c925756e29Jin Cao 19079d02b6021c640213888d446434e2c925756e29Jin Caoimport android.animation.ObjectAnimator; 20079d02b6021c640213888d446434e2c925756e29Jin Caoimport android.app.LoaderManager; 21079d02b6021c640213888d446434e2c925756e29Jin Caoimport android.content.Context; 22079d02b6021c640213888d446434e2c925756e29Jin Caoimport android.content.res.Resources; 23079d02b6021c640213888d446434e2c925756e29Jin Caoimport android.os.Bundle; 24079d02b6021c640213888d446434e2c925756e29Jin Caoimport android.support.annotation.LayoutRes; 25079d02b6021c640213888d446434e2c925756e29Jin Caoimport android.util.AttributeSet; 26079d02b6021c640213888d446434e2c925756e29Jin Caoimport android.view.LayoutInflater; 27079d02b6021c640213888d446434e2c925756e29Jin Caoimport android.view.View; 28079d02b6021c640213888d446434e2c925756e29Jin Caoimport android.view.ViewGroup; 29079d02b6021c640213888d446434e2c925756e29Jin Caoimport android.view.animation.DecelerateInterpolator; 305f9b22e817528d08813a2dfe031649e79f28fb2eRohan Shahimport android.widget.AbsListView; 31079d02b6021c640213888d446434e2c925756e29Jin Caoimport android.widget.ImageView; 32079d02b6021c640213888d446434e2c925756e29Jin Caoimport android.widget.LinearLayout; 33079d02b6021c640213888d446434e2c925756e29Jin Caoimport android.widget.TextView; 34079d02b6021c640213888d446434e2c925756e29Jin Cao 35079d02b6021c640213888d446434e2c925756e29Jin Caoimport com.android.mail.R; 36079d02b6021c640213888d446434e2c925756e29Jin Caoimport com.android.mail.browse.ConversationCursor; 37079d02b6021c640213888d446434e2c925756e29Jin Caoimport com.android.mail.providers.Folder; 38079d02b6021c640213888d446434e2c925756e29Jin Caoimport com.android.mail.utils.LogTag; 39079d02b6021c640213888d446434e2c925756e29Jin Cao 40079d02b6021c640213888d446434e2c925756e29Jin Cao/** 41079d02b6021c640213888d446434e2c925756e29Jin Cao * Base class to display tip teasers in the thread list. 42079d02b6021c640213888d446434e2c925756e29Jin Cao * Supports two-line text and start/end icons. 43079d02b6021c640213888d446434e2c925756e29Jin Cao */ 44079d02b6021c640213888d446434e2c925756e29Jin Caopublic abstract class ConversationTipView extends LinearLayout 45079d02b6021c640213888d446434e2c925756e29Jin Cao implements ConversationSpecialItemView, SwipeableItemView, View.OnClickListener { 46079d02b6021c640213888d446434e2c925756e29Jin Cao protected static final String LOG_TAG = LogTag.getLogTag(); 47079d02b6021c640213888d446434e2c925756e29Jin Cao 48079d02b6021c640213888d446434e2c925756e29Jin Cao protected Context mContext; 49079d02b6021c640213888d446434e2c925756e29Jin Cao protected AnimatedAdapter mAdapter; 50079d02b6021c640213888d446434e2c925756e29Jin Cao 51079d02b6021c640213888d446434e2c925756e29Jin Cao private int mScrollSlop; 52079d02b6021c640213888d446434e2c925756e29Jin Cao private int mShrinkAnimationDuration; 53079d02b6021c640213888d446434e2c925756e29Jin Cao private int mAnimatedHeight = -1; 54079d02b6021c640213888d446434e2c925756e29Jin Cao 55079d02b6021c640213888d446434e2c925756e29Jin Cao protected View mSwipeableContent; 56079d02b6021c640213888d446434e2c925756e29Jin Cao private View mContent; 57079d02b6021c640213888d446434e2c925756e29Jin Cao private TextView mText; 58079d02b6021c640213888d446434e2c925756e29Jin Cao 59079d02b6021c640213888d446434e2c925756e29Jin Cao public ConversationTipView(Context context) { 60079d02b6021c640213888d446434e2c925756e29Jin Cao this(context, null); 61079d02b6021c640213888d446434e2c925756e29Jin Cao } 62079d02b6021c640213888d446434e2c925756e29Jin Cao 63079d02b6021c640213888d446434e2c925756e29Jin Cao public ConversationTipView(Context context, AttributeSet attrs) { 64079d02b6021c640213888d446434e2c925756e29Jin Cao super(context, attrs); 65079d02b6021c640213888d446434e2c925756e29Jin Cao mContext = context; 66079d02b6021c640213888d446434e2c925756e29Jin Cao 67079d02b6021c640213888d446434e2c925756e29Jin Cao final Resources resources = context.getResources(); 68079d02b6021c640213888d446434e2c925756e29Jin Cao mScrollSlop = resources.getInteger(R.integer.swipeScrollSlop); 69079d02b6021c640213888d446434e2c925756e29Jin Cao mShrinkAnimationDuration = resources.getInteger( 70079d02b6021c640213888d446434e2c925756e29Jin Cao R.integer.shrink_animation_duration); 71079d02b6021c640213888d446434e2c925756e29Jin Cao 72079d02b6021c640213888d446434e2c925756e29Jin Cao // Inflate the actual content and add it to this view 73079d02b6021c640213888d446434e2c925756e29Jin Cao mContent = LayoutInflater.from(mContext).inflate(getChildLayout(), this, false); 74079d02b6021c640213888d446434e2c925756e29Jin Cao addView(mContent); 75079d02b6021c640213888d446434e2c925756e29Jin Cao setupViews(); 76079d02b6021c640213888d446434e2c925756e29Jin Cao } 77079d02b6021c640213888d446434e2c925756e29Jin Cao 78b62192b13a871f71cd9eafeac295e6ecb1d5953dJin Cao @Override 79b62192b13a871f71cd9eafeac295e6ecb1d5953dJin Cao public ViewGroup.LayoutParams getLayoutParams() { 80b62192b13a871f71cd9eafeac295e6ecb1d5953dJin Cao ViewGroup.LayoutParams params = super.getLayoutParams(); 81b62192b13a871f71cd9eafeac295e6ecb1d5953dJin Cao if (params != null) { 82b62192b13a871f71cd9eafeac295e6ecb1d5953dJin Cao params.width = ViewGroup.LayoutParams.MATCH_PARENT; 83b62192b13a871f71cd9eafeac295e6ecb1d5953dJin Cao params.height = ViewGroup.LayoutParams.WRAP_CONTENT; 84b62192b13a871f71cd9eafeac295e6ecb1d5953dJin Cao } 85b62192b13a871f71cd9eafeac295e6ecb1d5953dJin Cao return params; 86b62192b13a871f71cd9eafeac295e6ecb1d5953dJin Cao } 87b62192b13a871f71cd9eafeac295e6ecb1d5953dJin Cao 88079d02b6021c640213888d446434e2c925756e29Jin Cao protected @LayoutRes int getChildLayout() { 89079d02b6021c640213888d446434e2c925756e29Jin Cao // Should override setupViews as well if this is overridden. 90079d02b6021c640213888d446434e2c925756e29Jin Cao return R.layout.conversation_tip_view; 91079d02b6021c640213888d446434e2c925756e29Jin Cao } 92079d02b6021c640213888d446434e2c925756e29Jin Cao 93079d02b6021c640213888d446434e2c925756e29Jin Cao protected void setupViews() { 94079d02b6021c640213888d446434e2c925756e29Jin Cao // If this is overridden, child classes cannot rely on setText/getStartIconAttr/etc. 95079d02b6021c640213888d446434e2c925756e29Jin Cao mSwipeableContent = mContent.findViewById(R.id.conversation_tip_swipeable_content); 96079d02b6021c640213888d446434e2c925756e29Jin Cao mText = (TextView) mContent.findViewById(R.id.conversation_tip_text); 97079d02b6021c640213888d446434e2c925756e29Jin Cao final ImageView startImage = (ImageView) mContent.findViewById(R.id.conversation_tip_icon1); 98079d02b6021c640213888d446434e2c925756e29Jin Cao final ImageView dismiss = (ImageView) mContent.findViewById(R.id.dismiss_icon); 99079d02b6021c640213888d446434e2c925756e29Jin Cao 100079d02b6021c640213888d446434e2c925756e29Jin Cao // Bind content (text content must be bound by calling setText(..)) 101079d02b6021c640213888d446434e2c925756e29Jin Cao bindIcon(startImage, getStartIconAttr()); 102079d02b6021c640213888d446434e2c925756e29Jin Cao 103079d02b6021c640213888d446434e2c925756e29Jin Cao // Bind listeners 104079d02b6021c640213888d446434e2c925756e29Jin Cao dismiss.setOnClickListener(this); 105079d02b6021c640213888d446434e2c925756e29Jin Cao mText.setOnClickListener(getTextAreaOnClickListener()); 106079d02b6021c640213888d446434e2c925756e29Jin Cao } 107079d02b6021c640213888d446434e2c925756e29Jin Cao 108079d02b6021c640213888d446434e2c925756e29Jin Cao /** 109079d02b6021c640213888d446434e2c925756e29Jin Cao * Helper function to bind the additional attributes to the icon, or make the icon GONE. 110079d02b6021c640213888d446434e2c925756e29Jin Cao */ 111079d02b6021c640213888d446434e2c925756e29Jin Cao private void bindIcon(ImageView image, ImageAttrSet attr) { 112079d02b6021c640213888d446434e2c925756e29Jin Cao if (attr != null) { 113079d02b6021c640213888d446434e2c925756e29Jin Cao image.setVisibility(VISIBLE); 114079d02b6021c640213888d446434e2c925756e29Jin Cao image.setContentDescription(attr.contentDescription); 115079d02b6021c640213888d446434e2c925756e29Jin Cao // Must override resId for the actual icon, so no need to check -1 here. 116079d02b6021c640213888d446434e2c925756e29Jin Cao image.setImageResource(attr.resId); 117079d02b6021c640213888d446434e2c925756e29Jin Cao if (attr.background != -1) { 118079d02b6021c640213888d446434e2c925756e29Jin Cao image.setBackgroundResource(attr.background); 119079d02b6021c640213888d446434e2c925756e29Jin Cao } 120079d02b6021c640213888d446434e2c925756e29Jin Cao } else { 121079d02b6021c640213888d446434e2c925756e29Jin Cao image.setVisibility(GONE); 122079d02b6021c640213888d446434e2c925756e29Jin Cao } 123079d02b6021c640213888d446434e2c925756e29Jin Cao } 124079d02b6021c640213888d446434e2c925756e29Jin Cao 125079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 126079d02b6021c640213888d446434e2c925756e29Jin Cao protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { 127079d02b6021c640213888d446434e2c925756e29Jin Cao if (mAnimatedHeight == -1) { 128079d02b6021c640213888d446434e2c925756e29Jin Cao super.onMeasure(widthMeasureSpec, heightMeasureSpec); 129079d02b6021c640213888d446434e2c925756e29Jin Cao } else { 130079d02b6021c640213888d446434e2c925756e29Jin Cao setMeasuredDimension(View.MeasureSpec.getSize(widthMeasureSpec), mAnimatedHeight); 131079d02b6021c640213888d446434e2c925756e29Jin Cao } 132079d02b6021c640213888d446434e2c925756e29Jin Cao } 133079d02b6021c640213888d446434e2c925756e29Jin Cao 134079d02b6021c640213888d446434e2c925756e29Jin Cao protected ImageAttrSet getStartIconAttr() { 135079d02b6021c640213888d446434e2c925756e29Jin Cao return null; 136079d02b6021c640213888d446434e2c925756e29Jin Cao } 137079d02b6021c640213888d446434e2c925756e29Jin Cao 138079d02b6021c640213888d446434e2c925756e29Jin Cao protected void setText(CharSequence text) { 139079d02b6021c640213888d446434e2c925756e29Jin Cao mText.setText(text); 140079d02b6021c640213888d446434e2c925756e29Jin Cao } 141079d02b6021c640213888d446434e2c925756e29Jin Cao 142079d02b6021c640213888d446434e2c925756e29Jin Cao protected OnClickListener getTextAreaOnClickListener() { 143079d02b6021c640213888d446434e2c925756e29Jin Cao return null; 144079d02b6021c640213888d446434e2c925756e29Jin Cao } 145079d02b6021c640213888d446434e2c925756e29Jin Cao 146079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 147079d02b6021c640213888d446434e2c925756e29Jin Cao public void onClick(View view) { 148079d02b6021c640213888d446434e2c925756e29Jin Cao // Default on click for the default dismiss button 149079d02b6021c640213888d446434e2c925756e29Jin Cao dismiss(); 150079d02b6021c640213888d446434e2c925756e29Jin Cao } 151079d02b6021c640213888d446434e2c925756e29Jin Cao 152079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 153079d02b6021c640213888d446434e2c925756e29Jin Cao public void onUpdate(Folder folder, ConversationCursor cursor) { 154079d02b6021c640213888d446434e2c925756e29Jin Cao // Do nothing by default 155079d02b6021c640213888d446434e2c925756e29Jin Cao } 156079d02b6021c640213888d446434e2c925756e29Jin Cao 157079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 158079d02b6021c640213888d446434e2c925756e29Jin Cao public void onGetView() { 159079d02b6021c640213888d446434e2c925756e29Jin Cao // Do nothing by default 160079d02b6021c640213888d446434e2c925756e29Jin Cao } 161079d02b6021c640213888d446434e2c925756e29Jin Cao 162079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 163079d02b6021c640213888d446434e2c925756e29Jin Cao public int getPosition() { 164079d02b6021c640213888d446434e2c925756e29Jin Cao // By default the tip teasers go on top of the list. 165079d02b6021c640213888d446434e2c925756e29Jin Cao return 0; 166079d02b6021c640213888d446434e2c925756e29Jin Cao } 167079d02b6021c640213888d446434e2c925756e29Jin Cao 168079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 169079d02b6021c640213888d446434e2c925756e29Jin Cao public void setAdapter(AnimatedAdapter adapter) { 170079d02b6021c640213888d446434e2c925756e29Jin Cao mAdapter = adapter; 171079d02b6021c640213888d446434e2c925756e29Jin Cao } 172079d02b6021c640213888d446434e2c925756e29Jin Cao 173079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 174079d02b6021c640213888d446434e2c925756e29Jin Cao public void bindFragment(LoaderManager loaderManager, Bundle savedInstanceState) { 175079d02b6021c640213888d446434e2c925756e29Jin Cao // Do nothing by default 176079d02b6021c640213888d446434e2c925756e29Jin Cao } 177079d02b6021c640213888d446434e2c925756e29Jin Cao 178079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 179079d02b6021c640213888d446434e2c925756e29Jin Cao public void cleanup() { 180079d02b6021c640213888d446434e2c925756e29Jin Cao // Do nothing by default 181079d02b6021c640213888d446434e2c925756e29Jin Cao } 182079d02b6021c640213888d446434e2c925756e29Jin Cao 183079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 184079d02b6021c640213888d446434e2c925756e29Jin Cao public void onConversationSelected() { 185079d02b6021c640213888d446434e2c925756e29Jin Cao // Do nothing by default 186079d02b6021c640213888d446434e2c925756e29Jin Cao } 187079d02b6021c640213888d446434e2c925756e29Jin Cao 188079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 189079d02b6021c640213888d446434e2c925756e29Jin Cao public void onCabModeEntered() { 190079d02b6021c640213888d446434e2c925756e29Jin Cao // Do nothing by default 191079d02b6021c640213888d446434e2c925756e29Jin Cao } 192079d02b6021c640213888d446434e2c925756e29Jin Cao 193079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 194079d02b6021c640213888d446434e2c925756e29Jin Cao public void onCabModeExited() { 195079d02b6021c640213888d446434e2c925756e29Jin Cao // Do nothing by default 196079d02b6021c640213888d446434e2c925756e29Jin Cao } 197079d02b6021c640213888d446434e2c925756e29Jin Cao 198079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 199079d02b6021c640213888d446434e2c925756e29Jin Cao public boolean acceptsUserTaps() { 200079d02b6021c640213888d446434e2c925756e29Jin Cao return true; 201079d02b6021c640213888d446434e2c925756e29Jin Cao } 202079d02b6021c640213888d446434e2c925756e29Jin Cao 203079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 204079d02b6021c640213888d446434e2c925756e29Jin Cao public void onConversationListVisibilityChanged(boolean visible) { 205079d02b6021c640213888d446434e2c925756e29Jin Cao // Do nothing by default 206079d02b6021c640213888d446434e2c925756e29Jin Cao } 207079d02b6021c640213888d446434e2c925756e29Jin Cao 208079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 209079d02b6021c640213888d446434e2c925756e29Jin Cao public void saveInstanceState(Bundle outState) { 210079d02b6021c640213888d446434e2c925756e29Jin Cao // Do nothing by default 211079d02b6021c640213888d446434e2c925756e29Jin Cao } 212079d02b6021c640213888d446434e2c925756e29Jin Cao 213079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 214079d02b6021c640213888d446434e2c925756e29Jin Cao public boolean commitLeaveBehindItem() { 215079d02b6021c640213888d446434e2c925756e29Jin Cao // Tip has no leave-behind by default 216079d02b6021c640213888d446434e2c925756e29Jin Cao return false; 217079d02b6021c640213888d446434e2c925756e29Jin Cao } 218079d02b6021c640213888d446434e2c925756e29Jin Cao 219079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 220079d02b6021c640213888d446434e2c925756e29Jin Cao public SwipeableView getSwipeableView() { 221079d02b6021c640213888d446434e2c925756e29Jin Cao return SwipeableView.from(mSwipeableContent); 222079d02b6021c640213888d446434e2c925756e29Jin Cao } 223079d02b6021c640213888d446434e2c925756e29Jin Cao 224079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 225079d02b6021c640213888d446434e2c925756e29Jin Cao public boolean canChildBeDismissed() { 226079d02b6021c640213888d446434e2c925756e29Jin Cao return true; 227079d02b6021c640213888d446434e2c925756e29Jin Cao } 228079d02b6021c640213888d446434e2c925756e29Jin Cao 229079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 230079d02b6021c640213888d446434e2c925756e29Jin Cao public void dismiss() { 231079d02b6021c640213888d446434e2c925756e29Jin Cao startDestroyAnimation(); 232079d02b6021c640213888d446434e2c925756e29Jin Cao } 233079d02b6021c640213888d446434e2c925756e29Jin Cao 234079d02b6021c640213888d446434e2c925756e29Jin Cao @Override 235079d02b6021c640213888d446434e2c925756e29Jin Cao public float getMinAllowScrollDistance() { 236079d02b6021c640213888d446434e2c925756e29Jin Cao return mScrollSlop; 237079d02b6021c640213888d446434e2c925756e29Jin Cao } 238079d02b6021c640213888d446434e2c925756e29Jin Cao 239079d02b6021c640213888d446434e2c925756e29Jin Cao private void startDestroyAnimation() { 240079d02b6021c640213888d446434e2c925756e29Jin Cao final int start = getHeight(); 241079d02b6021c640213888d446434e2c925756e29Jin Cao final int end = 0; 242079d02b6021c640213888d446434e2c925756e29Jin Cao mAnimatedHeight = start; 243079d02b6021c640213888d446434e2c925756e29Jin Cao final ObjectAnimator heightAnimator = 244079d02b6021c640213888d446434e2c925756e29Jin Cao ObjectAnimator.ofInt(this, "animatedHeight", start, end); 245079d02b6021c640213888d446434e2c925756e29Jin Cao heightAnimator.setInterpolator(new DecelerateInterpolator(2.0f)); 246079d02b6021c640213888d446434e2c925756e29Jin Cao heightAnimator.setDuration(mShrinkAnimationDuration); 247079d02b6021c640213888d446434e2c925756e29Jin Cao heightAnimator.start(); 248079d02b6021c640213888d446434e2c925756e29Jin Cao 249079d02b6021c640213888d446434e2c925756e29Jin Cao /* 250079d02b6021c640213888d446434e2c925756e29Jin Cao * Ideally, we would like to call mAdapter.notifyDataSetChanged() in a listener's 251079d02b6021c640213888d446434e2c925756e29Jin Cao * onAnimationEnd(), but we are in the middle of a touch event, and this will cause all the 252079d02b6021c640213888d446434e2c925756e29Jin Cao * views to get recycled, which will cause problems. 253079d02b6021c640213888d446434e2c925756e29Jin Cao * 254079d02b6021c640213888d446434e2c925756e29Jin Cao * Instead, we'll just leave the item in the list with a height of 0, and the next 255079d02b6021c640213888d446434e2c925756e29Jin Cao * notifyDatasetChanged() will remove it from the adapter. 256079d02b6021c640213888d446434e2c925756e29Jin Cao */ 257079d02b6021c640213888d446434e2c925756e29Jin Cao } 258079d02b6021c640213888d446434e2c925756e29Jin Cao 259079d02b6021c640213888d446434e2c925756e29Jin Cao /** 260079d02b6021c640213888d446434e2c925756e29Jin Cao * This method is used by the animator. It is explicitly kept in proguard.flags to prevent it 261079d02b6021c640213888d446434e2c925756e29Jin Cao * from being removed, inlined, or obfuscated. 262079d02b6021c640213888d446434e2c925756e29Jin Cao * Edit ./vendor/unbundled/packages/apps/UnifiedGmail/proguard.flags 263079d02b6021c640213888d446434e2c925756e29Jin Cao * In the future, we want to use @Keep 264079d02b6021c640213888d446434e2c925756e29Jin Cao */ 265079d02b6021c640213888d446434e2c925756e29Jin Cao public void setAnimatedHeight(final int height) { 266079d02b6021c640213888d446434e2c925756e29Jin Cao mAnimatedHeight = height; 267079d02b6021c640213888d446434e2c925756e29Jin Cao requestLayout(); 268079d02b6021c640213888d446434e2c925756e29Jin Cao } 269079d02b6021c640213888d446434e2c925756e29Jin Cao 270079d02b6021c640213888d446434e2c925756e29Jin Cao public static class ImageAttrSet { 271079d02b6021c640213888d446434e2c925756e29Jin Cao // -1 for these resIds to not override the default value. 272079d02b6021c640213888d446434e2c925756e29Jin Cao public int resId; 273079d02b6021c640213888d446434e2c925756e29Jin Cao public int background; 274079d02b6021c640213888d446434e2c925756e29Jin Cao public String contentDescription; 275079d02b6021c640213888d446434e2c925756e29Jin Cao 276079d02b6021c640213888d446434e2c925756e29Jin Cao public ImageAttrSet(int resId, int background, String contentDescription) { 277079d02b6021c640213888d446434e2c925756e29Jin Cao this.resId = resId; 278079d02b6021c640213888d446434e2c925756e29Jin Cao this.background = background; 279079d02b6021c640213888d446434e2c925756e29Jin Cao this.contentDescription = contentDescription; 280079d02b6021c640213888d446434e2c925756e29Jin Cao } 281079d02b6021c640213888d446434e2c925756e29Jin Cao } 282079d02b6021c640213888d446434e2c925756e29Jin Cao} 283