2017-10-16 20:11:42 +00:00
/ *
2017-11-14 02:01:05 +00:00
* Copyright ( C ) 2014 - 2017 Open Whisper Systems
2012-07-17 02:56:10 +00:00
*
2011-12-20 18:20:44 +00:00
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2012-07-17 02:56:10 +00:00
*
2011-12-20 18:20:44 +00:00
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
* /
package org.thoughtcrime.securesms ;
import android.content.Context ;
2015-07-02 21:59:50 +00:00
import android.content.res.ColorStateList ;
2012-07-17 04:35:32 +00:00
import android.graphics.Typeface ;
2015-07-02 21:59:50 +00:00
import android.graphics.drawable.RippleDrawable ;
import android.os.Build.VERSION ;
import android.os.Build.VERSION_CODES ;
2015-10-16 20:59:40 +00:00
import android.support.annotation.NonNull ;
2018-04-07 01:15:24 +00:00
import android.support.annotation.Nullable ;
import android.text.style.StyleSpan ;
2011-12-20 18:20:44 +00:00
import android.util.AttributeSet ;
2015-10-16 20:59:40 +00:00
import android.view.View ;
2011-12-20 18:20:44 +00:00
import android.widget.RelativeLayout ;
import android.widget.TextView ;
2017-08-01 15:56:00 +00:00
import org.thoughtcrime.securesms.components.AlertView ;
2015-05-04 18:36:18 +00:00
import org.thoughtcrime.securesms.components.AvatarImageView ;
2015-11-24 15:06:41 +00:00
import org.thoughtcrime.securesms.components.DeliveryStatusView ;
2015-05-04 18:36:18 +00:00
import org.thoughtcrime.securesms.components.FromTextView ;
2015-10-16 20:59:40 +00:00
import org.thoughtcrime.securesms.components.ThumbnailView ;
2018-10-29 22:14:31 +00:00
import org.thoughtcrime.securesms.components.TypingIndicatorView ;
2012-10-28 23:04:24 +00:00
import org.thoughtcrime.securesms.database.model.ThreadRecord ;
2020-05-11 06:19:26 +00:00
import org.thoughtcrime.securesms.loki.api.MentionManagerUtilities ;
import org.thoughtcrime.securesms.loki.utilities.MentionUtilities ;
2017-10-16 20:11:42 +00:00
import org.thoughtcrime.securesms.mms.GlideRequests ;
2017-08-01 15:56:00 +00:00
import org.thoughtcrime.securesms.recipients.Recipient ;
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener ;
2018-04-07 01:15:24 +00:00
import org.thoughtcrime.securesms.search.model.MessageResult ;
2014-01-08 22:29:05 +00:00
import org.thoughtcrime.securesms.util.DateUtils ;
2019-02-01 17:06:59 +00:00
import org.thoughtcrime.securesms.util.SearchUtil ;
2018-07-24 16:34:21 +00:00
import org.thoughtcrime.securesms.util.ThemeUtil ;
2017-09-10 06:46:48 +00:00
import org.thoughtcrime.securesms.util.Util ;
2015-11-23 23:07:41 +00:00
import org.thoughtcrime.securesms.util.ViewUtil ;
2012-07-17 02:56:10 +00:00
2018-04-07 01:15:24 +00:00
import java.util.Collections ;
2015-03-19 20:08:48 +00:00
import java.util.Locale ;
2012-07-17 02:56:10 +00:00
import java.util.Set ;
2015-02-06 02:35:13 +00:00
2019-07-24 02:30:23 +00:00
import network.loki.messenger.R ;
2012-12-24 16:40:37 +00:00
public class ConversationListItem extends RelativeLayout
2017-08-01 15:56:00 +00:00
implements RecipientModifiedListener ,
2015-11-23 23:07:41 +00:00
BindableConversationListItem , Unbindable
2012-12-24 16:40:37 +00:00
{
2017-11-14 02:01:05 +00:00
@SuppressWarnings ( " unused " )
2014-02-19 20:29:00 +00:00
private final static String TAG = ConversationListItem . class . getSimpleName ( ) ;
2011-12-20 18:20:44 +00:00
2018-06-26 17:27:44 +00:00
private final static Typeface BOLD_TYPEFACE = Typeface . create ( " sans-serif-medium " , Typeface . NORMAL ) ;
private final static Typeface LIGHT_TYPEFACE = Typeface . create ( " sans-serif " , Typeface . NORMAL ) ;
2015-02-06 02:35:13 +00:00
2019-04-12 21:49:22 +00:00
private static final int MAX_SNIPPET_LENGTH = 500 ;
2018-10-29 22:14:31 +00:00
private Set < Long > selectedThreads ;
private Recipient recipient ;
private long threadId ;
private GlideRequests glideRequests ;
private View subjectContainer ;
private TextView subjectView ;
private TypingIndicatorView typingView ;
private FromTextView fromView ;
private TextView dateView ;
private TextView archivedView ;
private DeliveryStatusView deliveryStatusIndicator ;
private AlertView alertView ;
private TextView unreadIndicator ;
private long lastSeen ;
2015-11-24 15:06:41 +00:00
2017-11-14 02:01:05 +00:00
private int unreadCount ;
2015-05-04 18:36:18 +00:00
private AvatarImageView contactPhotoImage ;
2015-10-16 20:59:40 +00:00
private ThumbnailView thumbnailView ;
2012-07-17 02:56:10 +00:00
2013-04-26 01:59:49 +00:00
private int distributionType ;
2012-12-24 16:40:37 +00:00
public ConversationListItem ( Context context ) {
2015-08-06 23:28:51 +00:00
this ( context , null ) ;
2012-12-24 16:40:37 +00:00
}
2011-12-20 18:20:44 +00:00
2012-12-24 16:40:37 +00:00
public ConversationListItem ( Context context , AttributeSet attrs ) {
super ( context , attrs ) ;
}
2012-07-17 02:56:10 +00:00
2012-12-24 16:40:37 +00:00
@Override
protected void onFinishInflate ( ) {
2015-06-09 14:37:20 +00:00
super . onFinishInflate ( ) ;
2018-10-29 22:14:31 +00:00
this . subjectContainer = findViewById ( R . id . subject_container ) ;
2017-10-16 20:11:42 +00:00
this . subjectView = findViewById ( R . id . subject ) ;
2018-10-29 22:14:31 +00:00
this . typingView = findViewById ( R . id . typing_indicator ) ;
2017-10-16 20:11:42 +00:00
this . fromView = findViewById ( R . id . from ) ;
this . dateView = findViewById ( R . id . date ) ;
this . deliveryStatusIndicator = findViewById ( R . id . delivery_status ) ;
this . alertView = findViewById ( R . id . indicators_parent ) ;
this . contactPhotoImage = findViewById ( R . id . contact_photo_image ) ;
this . thumbnailView = findViewById ( R . id . thumbnail ) ;
2017-11-14 02:01:05 +00:00
this . archivedView = findViewById ( R . id . archived ) ;
this . unreadIndicator = findViewById ( R . id . unread_indicator ) ;
2015-11-12 22:44:25 +00:00
thumbnailView . setClickable ( false ) ;
2015-11-26 18:04:27 +00:00
ViewUtil . setTextViewGravityStart ( this . fromView , getContext ( ) ) ;
ViewUtil . setTextViewGravityStart ( this . subjectView , getContext ( ) ) ;
2011-12-20 18:20:44 +00:00
}
2012-07-17 02:56:10 +00:00
2017-10-16 20:11:42 +00:00
@Override
2018-01-25 03:17:44 +00:00
public void bind ( @NonNull ThreadRecord thread ,
2018-04-07 01:15:24 +00:00
@NonNull GlideRequests glideRequests ,
@NonNull Locale locale ,
2018-10-29 22:14:31 +00:00
@NonNull Set < Long > typingThreads ,
2018-04-07 01:15:24 +00:00
@NonNull Set < Long > selectedThreads ,
boolean batchMode )
{
2018-10-29 22:14:31 +00:00
bind ( thread , glideRequests , locale , typingThreads , selectedThreads , batchMode , null ) ;
2018-04-07 01:15:24 +00:00
}
public void bind ( @NonNull ThreadRecord thread ,
@NonNull GlideRequests glideRequests ,
@NonNull Locale locale ,
2018-10-29 22:14:31 +00:00
@NonNull Set < Long > typingThreads ,
2018-04-07 01:15:24 +00:00
@NonNull Set < Long > selectedThreads ,
boolean batchMode ,
@Nullable String highlightSubstring )
2015-10-16 20:59:40 +00:00
{
2013-04-26 01:59:49 +00:00
this . selectedThreads = selectedThreads ;
2017-08-01 15:56:00 +00:00
this . recipient = thread . getRecipient ( ) ;
2013-04-26 01:59:49 +00:00
this . threadId = thread . getThreadId ( ) ;
2017-10-16 20:11:42 +00:00
this . glideRequests = glideRequests ;
2017-11-14 02:01:05 +00:00
this . unreadCount = thread . getUnreadCount ( ) ;
2013-04-26 01:59:49 +00:00
this . distributionType = thread . getDistributionType ( ) ;
2017-02-14 06:35:47 +00:00
this . lastSeen = thread . getLastSeen ( ) ;
2011-12-20 18:20:44 +00:00
2017-08-01 15:56:00 +00:00
this . recipient . addListener ( this ) ;
2018-04-07 01:15:24 +00:00
if ( highlightSubstring ! = null ) {
2019-01-14 07:30:54 +00:00
String name = recipient . isLocalNumber ( ) ? getContext ( ) . getString ( R . string . note_to_self ) : recipient . getName ( ) ;
this . fromView . setText ( SearchUtil . getHighlightedSpan ( locale , ( ) - > new StyleSpan ( Typeface . BOLD ) , name , highlightSubstring ) ) ;
2018-04-07 01:15:24 +00:00
} else {
this . fromView . setText ( recipient , unreadCount = = 0 ) ;
}
2014-02-14 23:59:57 +00:00
2018-10-29 22:14:31 +00:00
if ( typingThreads . contains ( threadId ) ) {
this . subjectView . setVisibility ( INVISIBLE ) ;
this . typingView . setVisibility ( VISIBLE ) ;
this . typingView . startAnimation ( ) ;
} else {
this . typingView . setVisibility ( GONE ) ;
this . typingView . stopAnimation ( ) ;
this . subjectView . setVisibility ( VISIBLE ) ;
2019-04-12 21:49:22 +00:00
this . subjectView . setText ( getTrimmedSnippet ( thread . getDisplayBody ( getContext ( ) ) ) ) ;
2018-10-29 22:14:31 +00:00
this . subjectView . setTypeface ( unreadCount = = 0 ? LIGHT_TYPEFACE : BOLD_TYPEFACE ) ;
this . subjectView . setTextColor ( unreadCount = = 0 ? ThemeUtil . getThemedColor ( getContext ( ) , R . attr . conversation_list_item_subject_color )
: ThemeUtil . getThemedColor ( getContext ( ) , R . attr . conversation_list_item_unread_color ) ) ;
}
2015-02-06 02:35:13 +00:00
if ( thread . getDate ( ) > 0 ) {
2015-08-06 23:28:51 +00:00
CharSequence date = DateUtils . getBriefRelativeTimeSpanString ( getContext ( ) , locale , thread . getDate ( ) ) ;
2018-07-24 16:34:21 +00:00
dateView . setText ( date ) ;
2017-11-14 02:01:05 +00:00
dateView . setTypeface ( unreadCount = = 0 ? LIGHT_TYPEFACE : BOLD_TYPEFACE ) ;
2018-07-24 16:34:21 +00:00
dateView . setTextColor ( unreadCount = = 0 ? ThemeUtil . getThemedColor ( getContext ( ) , R . attr . conversation_list_item_date_color )
: ThemeUtil . getThemedColor ( getContext ( ) , R . attr . conversation_list_item_unread_color ) ) ;
2015-02-06 02:35:13 +00:00
}
2011-12-20 18:20:44 +00:00
2015-11-23 23:07:41 +00:00
if ( thread . isArchived ( ) ) {
this . archivedView . setVisibility ( View . VISIBLE ) ;
} else {
this . archivedView . setVisibility ( View . GONE ) ;
}
2015-11-24 15:06:41 +00:00
setStatusIcons ( thread ) ;
2018-01-25 03:17:44 +00:00
setThumbnailSnippet ( thread ) ;
2015-06-01 23:51:14 +00:00
setBatchState ( batchMode ) ;
2017-08-01 15:56:00 +00:00
setRippleColor ( recipient ) ;
2017-11-14 02:01:05 +00:00
setUnreadIndicator ( thread ) ;
2017-10-16 20:11:42 +00:00
this . contactPhotoImage . setAvatar ( glideRequests , recipient , true ) ;
2013-01-06 23:46:26 +00:00
}
2018-04-07 01:15:24 +00:00
public void bind ( @NonNull Recipient contact ,
@NonNull GlideRequests glideRequests ,
@NonNull Locale locale ,
@Nullable String highlightSubstring )
{
this . selectedThreads = Collections . emptySet ( ) ;
this . recipient = contact ;
this . glideRequests = glideRequests ;
this . recipient . addListener ( this ) ;
2019-01-14 07:30:54 +00:00
String name = recipient . isLocalNumber ( ) ? getContext ( ) . getString ( R . string . note_to_self ) : recipient . getName ( ) ;
fromView . setText ( SearchUtil . getHighlightedSpan ( locale , ( ) - > new StyleSpan ( Typeface . BOLD ) , name , highlightSubstring ) ) ;
2019-05-22 16:29:45 +00:00
subjectView . setText ( SearchUtil . getHighlightedSpan ( locale , ( ) - > new StyleSpan ( Typeface . BOLD ) , contact . getAddress ( ) . toString ( ) , highlightSubstring ) ) ;
2018-04-07 01:15:24 +00:00
dateView . setText ( " " ) ;
archivedView . setVisibility ( GONE ) ;
unreadIndicator . setVisibility ( GONE ) ;
deliveryStatusIndicator . setNone ( ) ;
alertView . setNone ( ) ;
thumbnailView . setVisibility ( GONE ) ;
setBatchState ( false ) ;
setRippleColor ( contact ) ;
contactPhotoImage . setAvatar ( glideRequests , recipient , true ) ;
}
public void bind ( @NonNull MessageResult messageResult ,
@NonNull GlideRequests glideRequests ,
@NonNull Locale locale ,
@Nullable String highlightSubstring )
{
this . selectedThreads = Collections . emptySet ( ) ;
2019-02-01 17:06:59 +00:00
this . recipient = messageResult . conversationRecipient ;
2018-04-07 01:15:24 +00:00
this . glideRequests = glideRequests ;
this . recipient . addListener ( this ) ;
fromView . setText ( recipient , true ) ;
2019-02-01 17:06:59 +00:00
subjectView . setText ( SearchUtil . getHighlightedSpan ( locale , ( ) - > new StyleSpan ( Typeface . BOLD ) , messageResult . bodySnippet , highlightSubstring ) ) ;
2018-04-07 01:15:24 +00:00
dateView . setText ( DateUtils . getBriefRelativeTimeSpanString ( getContext ( ) , locale , messageResult . receivedTimestampMs ) ) ;
archivedView . setVisibility ( GONE ) ;
unreadIndicator . setVisibility ( GONE ) ;
deliveryStatusIndicator . setNone ( ) ;
alertView . setNone ( ) ;
thumbnailView . setVisibility ( GONE ) ;
setBatchState ( false ) ;
setRippleColor ( recipient ) ;
contactPhotoImage . setAvatar ( glideRequests , recipient , true ) ;
}
2015-09-15 22:28:27 +00:00
@Override
2013-01-06 23:46:26 +00:00
public void unbind ( ) {
2017-08-01 15:56:00 +00:00
if ( this . recipient ! = null ) this . recipient . removeListener ( this ) ;
2011-12-20 18:20:44 +00:00
}
2012-07-17 02:56:10 +00:00
2015-06-01 23:51:14 +00:00
private void setBatchState ( boolean batch ) {
setSelected ( batch & & selectedThreads . contains ( threadId ) ) ;
2013-02-09 18:03:38 +00:00
}
2017-08-01 15:56:00 +00:00
public Recipient getRecipient ( ) {
return recipient ;
2011-12-20 18:20:44 +00:00
}
2012-07-17 02:56:10 +00:00
2011-12-20 18:20:44 +00:00
public long getThreadId ( ) {
return threadId ;
}
2012-07-17 02:56:10 +00:00
2017-11-14 02:01:05 +00:00
public int getUnreadCount ( ) {
return unreadCount ;
2015-12-03 20:36:47 +00:00
}
2013-04-26 01:59:49 +00:00
public int getDistributionType ( ) {
return distributionType ;
}
2017-02-14 06:35:47 +00:00
public long getLastSeen ( ) {
return lastSeen ;
}
2019-04-12 21:49:22 +00:00
private @NonNull CharSequence getTrimmedSnippet ( @NonNull CharSequence snippet ) {
2020-05-11 06:19:26 +00:00
MentionManagerUtilities . INSTANCE . populateUserHexEncodedPublicKeyCacheIfNeeded ( threadId , getContext ( ) ) ; // TODO: Terrible place to do this, but okay for now
2019-10-15 02:51:18 +00:00
snippet = MentionUtilities . highlightMentions ( snippet , threadId , getContext ( ) ) ;
2019-10-11 03:41:43 +00:00
return snippet . length ( ) < = MAX_SNIPPET_LENGTH ? snippet : snippet . subSequence ( 0 , MAX_SNIPPET_LENGTH ) ;
2019-04-12 21:49:22 +00:00
}
2018-01-25 03:17:44 +00:00
private void setThumbnailSnippet ( ThreadRecord thread ) {
2015-10-16 20:59:40 +00:00
if ( thread . getSnippetUri ( ) ! = null ) {
this . thumbnailView . setVisibility ( View . VISIBLE ) ;
2018-01-25 03:17:44 +00:00
this . thumbnailView . setImageResource ( glideRequests , thread . getSnippetUri ( ) ) ;
2015-10-16 20:59:40 +00:00
2018-10-29 22:14:31 +00:00
LayoutParams subjectParams = ( RelativeLayout . LayoutParams ) this . subjectContainer . getLayoutParams ( ) ;
2015-10-16 20:59:40 +00:00
subjectParams . addRule ( RelativeLayout . LEFT_OF , R . id . thumbnail ) ;
2015-12-25 11:09:26 +00:00
if ( VERSION . SDK_INT > = VERSION_CODES . JELLY_BEAN_MR1 ) {
subjectParams . addRule ( RelativeLayout . START_OF , R . id . thumbnail ) ;
}
2018-10-29 22:14:31 +00:00
this . subjectContainer . setLayoutParams ( subjectParams ) ;
2015-11-24 15:06:41 +00:00
this . post ( new ThumbnailPositioner ( thumbnailView , archivedView , deliveryStatusIndicator , dateView ) ) ;
2015-10-16 20:59:40 +00:00
} else {
this . thumbnailView . setVisibility ( View . GONE ) ;
2018-10-29 22:14:31 +00:00
LayoutParams subjectParams = ( RelativeLayout . LayoutParams ) this . subjectContainer . getLayoutParams ( ) ;
2017-11-15 23:49:45 +00:00
subjectParams . addRule ( RelativeLayout . LEFT_OF , R . id . status ) ;
2015-12-25 11:09:26 +00:00
if ( VERSION . SDK_INT > = VERSION_CODES . JELLY_BEAN_MR1 ) {
2017-11-15 23:49:45 +00:00
subjectParams . addRule ( RelativeLayout . START_OF , R . id . status ) ;
2015-12-25 11:09:26 +00:00
}
2018-10-29 22:14:31 +00:00
this . subjectContainer . setLayoutParams ( subjectParams ) ;
2015-10-16 20:59:40 +00:00
}
}
2015-11-24 15:06:41 +00:00
private void setStatusIcons ( ThreadRecord thread ) {
2017-10-04 18:50:12 +00:00
if ( ! thread . isOutgoing ( ) | | thread . isOutgoingCall ( ) | | thread . isVerificationStatusChange ( ) ) {
2015-11-24 15:06:41 +00:00
deliveryStatusIndicator . setNone ( ) ;
alertView . setNone ( ) ;
} else if ( thread . isFailed ( ) ) {
deliveryStatusIndicator . setNone ( ) ;
alertView . setFailed ( ) ;
} else if ( thread . isPendingInsecureSmsFallback ( ) ) {
deliveryStatusIndicator . setNone ( ) ;
alertView . setPendingApproval ( ) ;
} else {
alertView . setNone ( ) ;
2017-09-16 05:38:53 +00:00
if ( thread . isPending ( ) ) deliveryStatusIndicator . setPending ( ) ;
else if ( thread . isRemoteRead ( ) ) deliveryStatusIndicator . setRead ( ) ;
else if ( thread . isDelivered ( ) ) deliveryStatusIndicator . setDelivered ( ) ;
else deliveryStatusIndicator . setSent ( ) ;
2015-11-24 15:06:41 +00:00
}
}
2017-08-01 15:56:00 +00:00
private void setRippleColor ( Recipient recipient ) {
2015-07-02 21:59:50 +00:00
if ( VERSION . SDK_INT > = VERSION_CODES . LOLLIPOP ) {
( ( RippleDrawable ) ( getBackground ( ) ) . mutate ( ) )
2017-08-01 15:56:00 +00:00
. setColor ( ColorStateList . valueOf ( recipient . getColor ( ) . toConversationColor ( getContext ( ) ) ) ) ;
2015-07-02 21:59:50 +00:00
}
}
2017-11-14 02:01:05 +00:00
private void setUnreadIndicator ( ThreadRecord thread ) {
if ( thread . isOutgoing ( ) | | thread . getUnreadCount ( ) = = 0 ) {
unreadIndicator . setVisibility ( View . GONE ) ;
return ;
}
2018-09-24 22:34:21 +00:00
unreadIndicator . setText ( String . valueOf ( unreadCount ) ) ;
2017-11-14 02:01:05 +00:00
unreadIndicator . setVisibility ( View . VISIBLE ) ;
}
2012-12-24 16:40:37 +00:00
@Override
2017-08-01 15:56:00 +00:00
public void onModified ( final Recipient recipient ) {
2017-09-10 06:46:48 +00:00
Util . runOnMain ( ( ) - > {
2017-11-14 02:01:05 +00:00
fromView . setText ( recipient , unreadCount = = 0 ) ;
2017-10-16 20:11:42 +00:00
contactPhotoImage . setAvatar ( glideRequests , recipient , true ) ;
2017-09-10 06:46:48 +00:00
setRippleColor ( recipient ) ;
2012-12-24 16:40:37 +00:00
} ) ;
}
2015-11-23 23:07:41 +00:00
2015-11-30 18:36:56 +00:00
private static class ThumbnailPositioner implements Runnable {
private final View thumbnailView ;
private final View archivedView ;
2015-11-24 15:06:41 +00:00
private final View deliveryStatusView ;
2015-11-30 18:36:56 +00:00
private final View dateView ;
2017-10-16 20:11:42 +00:00
ThumbnailPositioner ( View thumbnailView , View archivedView , View deliveryStatusView , View dateView ) {
2015-11-24 15:06:41 +00:00
this . thumbnailView = thumbnailView ;
this . archivedView = archivedView ;
this . deliveryStatusView = deliveryStatusView ;
this . dateView = dateView ;
2015-11-30 18:36:56 +00:00
}
@Override
public void run ( ) {
LayoutParams thumbnailParams = ( RelativeLayout . LayoutParams ) thumbnailView . getLayoutParams ( ) ;
2015-11-24 15:06:41 +00:00
if ( archivedView . getVisibility ( ) = = View . VISIBLE & &
( archivedView . getWidth ( ) + deliveryStatusView . getWidth ( ) ) > dateView . getWidth ( ) )
{
2017-11-15 23:49:45 +00:00
thumbnailParams . addRule ( RelativeLayout . LEFT_OF , R . id . status ) ;
2015-12-25 11:09:26 +00:00
if ( VERSION . SDK_INT > = VERSION_CODES . JELLY_BEAN_MR1 ) {
2017-11-15 23:49:45 +00:00
thumbnailParams . addRule ( RelativeLayout . START_OF , R . id . status ) ;
2015-12-25 11:09:26 +00:00
}
2015-11-30 18:36:56 +00:00
} else {
thumbnailParams . addRule ( RelativeLayout . LEFT_OF , R . id . date ) ;
2015-12-25 11:09:26 +00:00
if ( VERSION . SDK_INT > = VERSION_CODES . JELLY_BEAN_MR1 ) {
thumbnailParams . addRule ( RelativeLayout . START_OF , R . id . date ) ;
}
2015-11-30 18:36:56 +00:00
}
thumbnailView . setLayoutParams ( thumbnailParams ) ;
}
}
2011-12-20 18:20:44 +00:00
}