kopia lustrzana https://github.com/ryukoposting/Signal-Android
Group member dialog update.
rodzic
d05a71c8fe
commit
28bbfd88b2
|
@ -1,131 +1,78 @@
|
|||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupMemberListView;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientExporter;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class GroupMembersDialog extends AsyncTask<Void, Void, List<Recipient>> {
|
||||
public final class GroupMembersDialog {
|
||||
|
||||
private static final String TAG = GroupMembersDialog.class.getSimpleName();
|
||||
private final Context context;
|
||||
private final Recipient groupRecipient;
|
||||
private final Lifecycle lifecycle;
|
||||
|
||||
private final Recipient recipient;
|
||||
private final Context context;
|
||||
|
||||
public GroupMembersDialog(Context context, Recipient recipient) {
|
||||
this.recipient = recipient;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreExecute() {}
|
||||
|
||||
@Override
|
||||
protected List<Recipient> doInBackground(Void... params) {
|
||||
return DatabaseFactory.getGroupDatabase(context).getGroupMembers(recipient.requireGroupId(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostExecute(List<Recipient> members) {
|
||||
GroupMembers groupMembers = new GroupMembers(members);
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle(R.string.ConversationActivity_group_members);
|
||||
builder.setIconAttribute(R.attr.group_members_dialog_icon);
|
||||
builder.setCancelable(true);
|
||||
builder.setItems(groupMembers.getRecipientStrings(), new GroupMembersOnClickListener(context, groupMembers));
|
||||
builder.setPositiveButton(android.R.string.ok, null);
|
||||
builder.show();
|
||||
public GroupMembersDialog(@NonNull Context context,
|
||||
@NonNull Recipient groupRecipient,
|
||||
@NonNull Lifecycle lifecycle)
|
||||
{
|
||||
this.context = context;
|
||||
this.groupRecipient = groupRecipient;
|
||||
this.lifecycle = lifecycle;
|
||||
}
|
||||
|
||||
public void display() {
|
||||
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
SimpleTask.run(
|
||||
lifecycle,
|
||||
() -> DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupRecipient.requireGroupId(), true),
|
||||
members -> {
|
||||
AlertDialog dialog = new AlertDialog.Builder(context)
|
||||
.setTitle(R.string.ConversationActivity_group_members)
|
||||
.setIconAttribute(R.attr.group_members_dialog_icon)
|
||||
.setCancelable(true)
|
||||
.setView(R.layout.dialog_group_members)
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.show();
|
||||
|
||||
GroupMemberListView memberListView = dialog.findViewById(R.id.list_members);
|
||||
|
||||
ArrayList<GroupMemberEntry.FullMember> pendingMembers = new ArrayList<>(members.size());
|
||||
for (Recipient member : members) {
|
||||
GroupMemberEntry.FullMember entry = new GroupMemberEntry.FullMember(member);
|
||||
|
||||
entry.setOnClick(() -> contactClick(member));
|
||||
|
||||
if (member.isLocalNumber()) {
|
||||
pendingMembers.add(0, entry);
|
||||
} else {
|
||||
pendingMembers.add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
//noinspection ConstantConditions
|
||||
memberListView.setMembers(pendingMembers);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private static class GroupMembersOnClickListener implements DialogInterface.OnClickListener {
|
||||
private final GroupMembers groupMembers;
|
||||
private final Context context;
|
||||
private void contactClick(@NonNull Recipient recipient) {
|
||||
if (recipient.getContactUri() != null) {
|
||||
Intent intent = new Intent(context, RecipientPreferenceActivity.class);
|
||||
intent.putExtra(RecipientPreferenceActivity.RECIPIENT_ID, recipient.getId());
|
||||
|
||||
public GroupMembersOnClickListener(Context context, GroupMembers members) {
|
||||
this.context = context;
|
||||
this.groupMembers = members;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int item) {
|
||||
Recipient recipient = groupMembers.get(item);
|
||||
|
||||
if (recipient.getContactUri() != null) {
|
||||
Intent intent = new Intent(context, RecipientPreferenceActivity.class);
|
||||
intent.putExtra(RecipientPreferenceActivity.RECIPIENT_ID, recipient.getId());
|
||||
|
||||
context.startActivity(intent);
|
||||
} else {
|
||||
context.startActivity(RecipientExporter.export(recipient).asAddContactIntent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a List of Recipient (just like @class Recipients),
|
||||
* but with focus on the order of the Recipients.
|
||||
* So that the order of the RecipientStrings[] matches
|
||||
* the internal order.
|
||||
*
|
||||
* @author Christoph Haefner
|
||||
*/
|
||||
private class GroupMembers {
|
||||
private final String TAG = GroupMembers.class.getSimpleName();
|
||||
|
||||
private final LinkedList<Recipient> members = new LinkedList<>();
|
||||
|
||||
public GroupMembers(List<Recipient> recipients) {
|
||||
for (Recipient recipient : recipients) {
|
||||
if (recipient.isLocalNumber()) {
|
||||
members.push(recipient);
|
||||
} else {
|
||||
members.add(recipient);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getRecipientStrings() {
|
||||
List<String> recipientStrings = new LinkedList<>();
|
||||
|
||||
for (Recipient recipient : members) {
|
||||
if (recipient.isLocalNumber()) {
|
||||
recipientStrings.add(context.getString(R.string.GroupMembersDialog_you));
|
||||
} else {
|
||||
String name = getRecipientName(recipient);
|
||||
recipientStrings.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
return recipientStrings.toArray(new String[members.size()]);
|
||||
}
|
||||
|
||||
private String getRecipientName(Recipient recipient) {
|
||||
if (FeatureFlags.profileDisplay()) return recipient.getDisplayName(context);
|
||||
|
||||
String name = recipient.toShortString(context);
|
||||
|
||||
if (recipient.getName(context) == null && !recipient.getProfileName().isEmpty()) {
|
||||
name += " ~" + recipient.getProfileName().toString();
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
public Recipient get(int index) {
|
||||
return members.get(index);
|
||||
context.startActivity(intent);
|
||||
} else {
|
||||
context.startActivity(RecipientExporter.export(recipient).asAddContactIntent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,11 @@ import org.thoughtcrime.securesms.color.MaterialColor;
|
|||
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientExporter;
|
||||
import org.thoughtcrime.securesms.util.AvatarUtil;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
|
||||
import java.util.Objects;
|
||||
|
@ -109,6 +111,15 @@ public final class AvatarImageView extends AppCompatImageView {
|
|||
this.fallbackPhotoProvider = fallbackPhotoProvider;
|
||||
}
|
||||
|
||||
public void setRecipient(@NonNull Recipient recipient) {
|
||||
if (recipient.isLocalNumber()) {
|
||||
setAvatar(GlideApp.with(this), null, false);
|
||||
AvatarUtil.loadIconIntoImageView(recipient, this);
|
||||
} else {
|
||||
setAvatar(GlideApp.with(this), recipient, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void setAvatar(@NonNull GlideRequests requestManager, @Nullable Recipient recipient, boolean quickContactEnabled) {
|
||||
if (recipient != null) {
|
||||
RecipientContactPhoto photo = new RecipientContactPhoto(recipient);
|
||||
|
|
|
@ -1196,7 +1196,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
}
|
||||
|
||||
private void handleDisplayGroupRecipients() {
|
||||
new GroupMembersDialog(this, getRecipient()).display();
|
||||
new GroupMembersDialog(this, getRecipient(), getLifecycle()).display();
|
||||
}
|
||||
|
||||
private void handleAddToContacts() {
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package org.thoughtcrime.securesms.groups.ui;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
||||
public abstract class GroupMemberEntry {
|
||||
|
||||
private @Nullable Runnable onClick;
|
||||
|
||||
private GroupMemberEntry() {
|
||||
}
|
||||
|
||||
public void setOnClick(@NonNull Runnable onClick) {
|
||||
this.onClick = onClick;
|
||||
}
|
||||
|
||||
public @Nullable Runnable getOnClick() {
|
||||
return onClick;
|
||||
}
|
||||
|
||||
public static class FullMember extends GroupMemberEntry {
|
||||
|
||||
private final Recipient member;
|
||||
|
||||
public FullMember(@NonNull Recipient member) {
|
||||
this.member = member;
|
||||
}
|
||||
|
||||
public Recipient getMember() {
|
||||
return member;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
package org.thoughtcrime.securesms.groups.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.AvatarImageView;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
final class GroupMemberListAdapter extends RecyclerView.Adapter<GroupMemberListAdapter.ViewHolder> {
|
||||
|
||||
private static final int FULL_MEMBER = 0;
|
||||
|
||||
private final ArrayList<GroupMemberEntry> data = new ArrayList<>();
|
||||
|
||||
void updateData(@NonNull Collection<? extends GroupMemberEntry> recipients) {
|
||||
data.clear();
|
||||
data.addAll(recipients);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
switch (viewType) {
|
||||
case FULL_MEMBER:
|
||||
return new FullMemberViewHolder(LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.group_recipient_list_item,
|
||||
parent, false));
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
holder.bind(data.get(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
GroupMemberEntry groupMemberEntry = data.get(position);
|
||||
|
||||
if (groupMemberEntry instanceof GroupMemberEntry.FullMember) {
|
||||
return FULL_MEMBER;
|
||||
}
|
||||
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
static abstract class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
final Context context;
|
||||
private final AvatarImageView avatar;
|
||||
private final TextView recipient;
|
||||
final PopupMenuView popupMenu;
|
||||
|
||||
ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
|
||||
context = itemView.getContext();
|
||||
avatar = itemView.findViewById(R.id.recipient_avatar);
|
||||
recipient = itemView.findViewById(R.id.recipient_name);
|
||||
popupMenu = itemView.findViewById(R.id.popupMenu);
|
||||
}
|
||||
|
||||
void bindRecipient(@NonNull Recipient recipient) {
|
||||
String displayName = recipient.isLocalNumber() ? context.getString(R.string.GroupMembersDialog_you)
|
||||
: recipient.getDisplayName(itemView.getContext());
|
||||
bindImageAndText(recipient, displayName);
|
||||
}
|
||||
|
||||
void bindImageAndText(@NonNull Recipient recipient, @NonNull String displayText) {
|
||||
this.recipient.setText(displayText);
|
||||
this.avatar.setRecipient(recipient);
|
||||
}
|
||||
|
||||
void bind(@NonNull GroupMemberEntry memberEntry) {
|
||||
Runnable onClick = memberEntry.getOnClick();
|
||||
View.OnClickListener onClickListener = v -> { if (onClick != null) onClick.run(); };
|
||||
|
||||
this.avatar.setOnClickListener(onClickListener);
|
||||
this.recipient.setOnClickListener(onClickListener);
|
||||
}
|
||||
}
|
||||
|
||||
final static class FullMemberViewHolder extends ViewHolder {
|
||||
|
||||
FullMemberViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
void bind(@NonNull GroupMemberEntry memberEntry) {
|
||||
super.bind(memberEntry);
|
||||
|
||||
GroupMemberEntry.FullMember fullMember = (GroupMemberEntry.FullMember) memberEntry;
|
||||
|
||||
bindRecipient(fullMember.getMember());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package org.thoughtcrime.securesms.groups.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public final class GroupMemberListView extends RecyclerView {
|
||||
|
||||
private final GroupMemberListAdapter membersAdapter = new GroupMemberListAdapter();
|
||||
private int maxHeight;
|
||||
|
||||
public GroupMemberListView(@NonNull Context context) {
|
||||
super(context);
|
||||
initialize(context, null);
|
||||
}
|
||||
|
||||
public GroupMemberListView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initialize(context, attrs);
|
||||
}
|
||||
|
||||
public GroupMemberListView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
initialize(context, attrs);
|
||||
}
|
||||
|
||||
private void initialize(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
setHasFixedSize(true);
|
||||
setLayoutManager(new LinearLayoutManager(context));
|
||||
setAdapter(membersAdapter);
|
||||
|
||||
if (attrs != null) {
|
||||
TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.GroupMemberListView, 0, 0);
|
||||
try {
|
||||
maxHeight = typedArray.getDimensionPixelSize(R.styleable.GroupMemberListView_maxHeight, 0);
|
||||
} finally {
|
||||
typedArray.recycle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setMembers(@NonNull Collection<? extends GroupMemberEntry> recipients) {
|
||||
membersAdapter.updateData(recipients);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthSpec, int heightSpec) {
|
||||
if (maxHeight > 0) {
|
||||
heightSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
|
||||
}
|
||||
super.onMeasure(widthSpec, heightSpec);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package org.thoughtcrime.securesms.groups.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.IdRes;
|
||||
import androidx.annotation.MenuRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.PopupMenu;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
||||
public final class PopupMenuView extends View {
|
||||
|
||||
private @MenuRes int menu;
|
||||
private @Nullable ItemClick callback;
|
||||
|
||||
public PopupMenuView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public PopupMenuView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public PopupMenuView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setBackgroundResource(R.drawable.ic_more_vert_24);
|
||||
|
||||
setOnClickListener(v -> {
|
||||
if (callback != null) {
|
||||
PopupMenu popup = new PopupMenu(getContext(), v);
|
||||
MenuInflater inflater = popup.getMenuInflater();
|
||||
|
||||
inflater.inflate(menu, popup.getMenu());
|
||||
|
||||
popup.setOnMenuItemClickListener(item -> callback.onItemClick(item.getItemId()));
|
||||
popup.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setMenu(@MenuRes int menu, @NonNull ItemClick callback) {
|
||||
this.menu = menu;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public interface ItemClick {
|
||||
boolean onItemClick(@IdRes int menuItemId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<org.thoughtcrime.securesms.groups.ui.GroupMemberListView
|
||||
android:id="@+id/list_members"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:scrollIndicators="top|bottom"
|
||||
android:scrollbars="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:maxHeight="280dp"
|
||||
tools:ignore="RtlSymmetry,UnusedAttribute"
|
||||
tools:listitem="@layout/group_recipient_list_item" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp">
|
||||
|
||||
<org.thoughtcrime.securesms.components.AvatarImageView
|
||||
android:id="@+id/recipient_avatar"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/recipient_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:gravity="start|center_vertical"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="?title_text_color_primary"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/recipient_avatar"
|
||||
app:layout_constraintEnd_toStartOf="@+id/popupMenu"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
app:layout_constraintStart_toEndOf="@+id/recipient_avatar"
|
||||
app:layout_constraintTop_toTopOf="@+id/recipient_avatar"
|
||||
tools:text="@tools:sample/full_names" />
|
||||
|
||||
<org.thoughtcrime.securesms.groups.ui.PopupMenuView
|
||||
android:id="@+id/popupMenu"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -286,11 +286,16 @@
|
|||
</attr>
|
||||
</declare-styleable>
|
||||
|
||||
<attr name="minWidth" format="dimension" />
|
||||
<attr name="maxWidth" format="dimension" />
|
||||
<attr name="minHeight" format="dimension" />
|
||||
<attr name="maxHeight" format="dimension" />
|
||||
|
||||
<declare-styleable name="ThumbnailView">
|
||||
<attr name="minWidth" format="dimension" />
|
||||
<attr name="maxWidth" format="dimension" />
|
||||
<attr name="minHeight" format="dimension" />
|
||||
<attr name="maxHeight" format="dimension" />
|
||||
<attr name="minWidth" />
|
||||
<attr name="maxWidth" />
|
||||
<attr name="minHeight" />
|
||||
<attr name="maxHeight" />
|
||||
<attr name="thumbnail_radius" format="dimension" />
|
||||
<attr name="thumbnail_fit" format="enum">
|
||||
<enum name="center_crop" value="0" />
|
||||
|
@ -479,4 +484,8 @@
|
|||
<attr name="thumbTouchRadius" format="dimension" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="GroupMemberListView">
|
||||
<attr name="maxHeight" />
|
||||
</declare-styleable>
|
||||
|
||||
</resources>
|
||||
|
|
Ładowanie…
Reference in New Issue