Started using friends capabilities for group chat and LIME
This commit is contained in:
parent
134123358b
commit
4363a0659d
11 changed files with 233 additions and 78 deletions
|
@ -27,6 +27,7 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.HorizontalScrollView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
|
@ -52,6 +53,7 @@ import org.linphone.core.Address;
|
|||
import org.linphone.core.ChatRoom;
|
||||
import org.linphone.core.ChatRoomListenerStub;
|
||||
import org.linphone.core.Core;
|
||||
import org.linphone.core.FriendCapability;
|
||||
import org.linphone.core.ProxyConfig;
|
||||
import org.linphone.fragments.FragmentsAvailable;
|
||||
import org.linphone.mediastream.Log;
|
||||
|
@ -134,7 +136,11 @@ public class ChatRoomCreationFragment extends Fragment
|
|||
|
||||
mSearchAdapter =
|
||||
new SearchContactsAdapter(
|
||||
null, mContactsFetchInProgress, this, !mCreateGroupChatRoom);
|
||||
null,
|
||||
mContactsFetchInProgress,
|
||||
this,
|
||||
!mCreateGroupChatRoom,
|
||||
mChatRoomEncrypted);
|
||||
|
||||
mSearchField = view.findViewById(R.id.searchField);
|
||||
mSearchField.setOnQueryTextListener(
|
||||
|
@ -155,24 +161,32 @@ public class ChatRoomCreationFragment extends Fragment
|
|||
mAllContactsToggle = view.findViewById(R.id.layout_all_contacts);
|
||||
|
||||
mSecurityToggle = view.findViewById(R.id.security_toogle);
|
||||
mSecurityToggle.setOnCheckedChangeListener(
|
||||
new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
setSecurityEnabled(isChecked);
|
||||
}
|
||||
});
|
||||
mSecurityToggleOn = view.findViewById(R.id.security_toogle_on);
|
||||
mSecurityToggleOff = view.findViewById(R.id.security_toogle_off);
|
||||
mSecurityToggleOn.setOnClickListener(
|
||||
new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mSecurityToggle.setChecked(true);
|
||||
setSecurityEnabled(true);
|
||||
}
|
||||
});
|
||||
mSecurityToggleOff.setOnClickListener(
|
||||
new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mSecurityToggle.setChecked(false);
|
||||
setSecurityEnabled(false);
|
||||
}
|
||||
});
|
||||
|
||||
mSecurityToggle.setChecked(mChatRoomEncrypted);
|
||||
mSearchAdapter.setSecurityEnabled(mChatRoomEncrypted);
|
||||
ProxyConfig lpc = LinphoneManager.getLc().getDefaultProxyConfig();
|
||||
if ((mChatRoomSubject != null && mChatRoomAddress != null)
|
||||
|| (lpc == null || lpc.getConferenceFactoryUri() == null)) {
|
||||
|
@ -236,7 +250,7 @@ public class ChatRoomCreationFragment extends Fragment
|
|||
mWaitLayout.setVisibility(View.GONE);
|
||||
LinphoneActivity.instance().displayChatRoomError();
|
||||
Log.e(
|
||||
"Group chat room for address "
|
||||
"[Chat Room Creation] Group chat room for address "
|
||||
+ cr.getPeerAddress()
|
||||
+ " has failed !");
|
||||
}
|
||||
|
@ -286,6 +300,30 @@ public class ChatRoomCreationFragment extends Fragment
|
|||
super.onPause();
|
||||
}
|
||||
|
||||
private void setSecurityEnabled(boolean enabled) {
|
||||
mChatRoomEncrypted = enabled;
|
||||
mSecurityToggle.setChecked(mChatRoomEncrypted);
|
||||
mSearchAdapter.setSecurityEnabled(mChatRoomEncrypted);
|
||||
|
||||
if (enabled) {
|
||||
// Remove all contacts added before LIME switch was set
|
||||
// and that can stay because they don't have the capability
|
||||
for (ContactAddress ca : mContactsSelected) {
|
||||
mContactsSelectedLayout.removeAllViews();
|
||||
if (ca.isSelect() && !ca.hasCapability(FriendCapability.LimeX3Dh)) {
|
||||
mContactsSelected.remove(getIndexOfCa(ca, mContactsSelected));
|
||||
}
|
||||
for (ContactAddress contactAddress : mContactsSelected) {
|
||||
if (contactAddress.getView() != null) {
|
||||
mContactsSelectedLayout.addView(contactAddress.getView());
|
||||
}
|
||||
}
|
||||
mSearchAdapter.setContactsSelectedList(mContactsSelected);
|
||||
mContactsSelectedLayout.invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void displayChatCreation() {
|
||||
mNextButton.setVisibility(View.VISIBLE);
|
||||
mNextButton.setEnabled(mContactsSelected.size() > 0);
|
||||
|
@ -507,6 +545,21 @@ public class ChatRoomCreationFragment extends Fragment
|
|||
Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
ProxyConfig lpc = lc.getDefaultProxyConfig();
|
||||
boolean createEncryptedChatRoom = mSecurityToggle.isChecked();
|
||||
|
||||
if (createEncryptedChatRoom && !ca.hasCapability(FriendCapability.LimeX3Dh)) {
|
||||
Log.w(
|
||||
"[Chat Room Creation] Contact "
|
||||
+ ca.getContact()
|
||||
+ " doesn't have LIME X3DH capability !");
|
||||
return;
|
||||
} else if (mCreateGroupChatRoom && !ca.hasCapability(FriendCapability.GroupChat)) {
|
||||
Log.w(
|
||||
"[Chat Room Creation] Contact "
|
||||
+ ca.getContact()
|
||||
+ " doesn't have group chat capability !");
|
||||
return;
|
||||
}
|
||||
|
||||
if (lpc == null || lpc.getConferenceFactoryUri() == null || !mCreateGroupChatRoom) {
|
||||
if (createEncryptedChatRoom && lpc != null && lpc.getConferenceFactoryUri() != null) {
|
||||
mChatRoom =
|
||||
|
|
|
@ -245,6 +245,8 @@ class AsyncContactsLoader extends AsyncTask<Void, Void, AsyncContactsLoader.Asyn
|
|||
contact.createOrUpdateFriendFromNativeContact();
|
||||
}
|
||||
|
||||
ContactsManager.getInstance().clearGroupChatContacts();
|
||||
ContactsManager.getInstance().clearLimeX3dhContacts();
|
||||
// Now that contact fetching is asynchronous, this is required to ensure
|
||||
// presence subscription event will be sent with all friends
|
||||
for (FriendList list : LinphoneManager.getLc().getFriendsLists()) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import android.view.View;
|
|||
import java.io.Serializable;
|
||||
import org.linphone.core.Address;
|
||||
import org.linphone.core.Factory;
|
||||
import org.linphone.core.FriendCapability;
|
||||
|
||||
public class ContactAddress implements Serializable {
|
||||
private LinphoneContact mContact;
|
||||
|
@ -118,6 +119,10 @@ public class ContactAddress implements Serializable {
|
|||
return mIsLinphoneContact;
|
||||
}
|
||||
|
||||
public boolean hasCapability(FriendCapability capability) {
|
||||
return mContact.hasFriendCapability(capability);
|
||||
}
|
||||
|
||||
private void init(LinphoneContact c, String a, String pn, boolean isLC) {
|
||||
mContact = c;
|
||||
mAddress = a;
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.linphone.core.ChatRoom;
|
|||
import org.linphone.core.ChatRoomListenerStub;
|
||||
import org.linphone.core.Core;
|
||||
import org.linphone.core.Factory;
|
||||
import org.linphone.core.FriendCapability;
|
||||
import org.linphone.core.PresenceBasicStatus;
|
||||
import org.linphone.core.PresenceModel;
|
||||
import org.linphone.core.ProxyConfig;
|
||||
|
@ -297,9 +298,9 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
|
|||
v.findViewById(R.id.contact_chat_secured).setTag(value);
|
||||
}
|
||||
|
||||
if (v.findViewById(R.id.friendLinphone).getVisibility()
|
||||
== View.VISIBLE /* TODO Does mContact have LIME capability ?*/
|
||||
&& lpc.getConferenceFactoryUri() != null) {
|
||||
if (v.findViewById(R.id.friendLinphone).getVisibility() == View.VISIBLE
|
||||
&& lpc.getConferenceFactoryUri() != null
|
||||
&& mContact.hasFriendCapability(FriendCapability.LimeX3Dh)) {
|
||||
v.findViewById(R.id.contact_chat_secured).setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
v.findViewById(R.id.contact_chat_secured).setVisibility(View.GONE);
|
||||
|
|
|
@ -49,6 +49,7 @@ import org.linphone.R;
|
|||
import org.linphone.core.Address;
|
||||
import org.linphone.core.Core;
|
||||
import org.linphone.core.Friend;
|
||||
import org.linphone.core.FriendCapability;
|
||||
import org.linphone.core.FriendList;
|
||||
import org.linphone.core.FriendListListener;
|
||||
import org.linphone.core.MagicSearch;
|
||||
|
@ -59,7 +60,7 @@ import org.linphone.settings.LinphonePreferences;
|
|||
public class ContactsManager extends ContentObserver implements FriendListListener {
|
||||
private static ContactsManager sInstance;
|
||||
|
||||
private List<LinphoneContact> mContacts, mSipContacts;
|
||||
private List<LinphoneContact> mContacts, mSipContacts, mGroupChatContacts, mLimeX3dhContacts;
|
||||
private ArrayList<ContactsUpdatedListener> mContactsUpdatedListeners;
|
||||
private MagicSearch mMagicSearch;
|
||||
private final Bitmap mDefaultAvatar;
|
||||
|
@ -80,6 +81,9 @@ public class ContactsManager extends ContentObserver implements FriendListListen
|
|||
mContactsUpdatedListeners = new ArrayList<>();
|
||||
mContacts = new ArrayList<>();
|
||||
mSipContacts = new ArrayList<>();
|
||||
mGroupChatContacts = new ArrayList<>();
|
||||
mLimeX3dhContacts = new ArrayList<>();
|
||||
|
||||
if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null) {
|
||||
mMagicSearch = LinphoneManager.getLcIfManagerNotDestroyedOrNull().createMagicSearch();
|
||||
}
|
||||
|
@ -127,6 +131,22 @@ public class ContactsManager extends ContentObserver implements FriendListListen
|
|||
mSipContacts = c;
|
||||
}
|
||||
|
||||
public synchronized List<LinphoneContact> getGroupChatContacts() {
|
||||
return mGroupChatContacts;
|
||||
}
|
||||
|
||||
synchronized void clearGroupChatContacts() {
|
||||
mGroupChatContacts.clear();
|
||||
}
|
||||
|
||||
public synchronized List<LinphoneContact> getLimeX3dhContacts() {
|
||||
return mLimeX3dhContacts;
|
||||
}
|
||||
|
||||
synchronized void clearLimeX3dhContacts() {
|
||||
mLimeX3dhContacts.clear();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
if (lc != null) {
|
||||
|
@ -379,10 +399,27 @@ public class ContactsManager extends ContentObserver implements FriendListListen
|
|||
|
||||
private synchronized boolean refreshSipContact(Friend lf) {
|
||||
LinphoneContact contact = (LinphoneContact) lf.getUserData();
|
||||
if (contact != null && !mSipContacts.contains(contact)) {
|
||||
mSipContacts.add(contact);
|
||||
Collections.sort(mSipContacts);
|
||||
return true;
|
||||
if (contact != null) {
|
||||
if (lf.hasCapability(FriendCapability.GroupChat)
|
||||
&& !mGroupChatContacts.contains(contact)) {
|
||||
mGroupChatContacts.add(contact);
|
||||
Collections.sort(mGroupChatContacts);
|
||||
Log.i("[Contacts Manager] Contact " + contact + " has group chat capability");
|
||||
|
||||
// Contact may only have LimeX3DH capability if it already has GroupChat capability
|
||||
if (lf.hasCapability(FriendCapability.LimeX3Dh)
|
||||
&& !mLimeX3dhContacts.contains(contact)) {
|
||||
mLimeX3dhContacts.add(contact);
|
||||
Collections.sort(mLimeX3dhContacts);
|
||||
Log.i("[Contacts Manager] Contact " + contact + " has lime x3dh capability");
|
||||
}
|
||||
}
|
||||
|
||||
if (!mSipContacts.contains(contact)) {
|
||||
mSipContacts.add(contact);
|
||||
Collections.sort(mSipContacts);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.linphone.LinphoneManager;
|
|||
import org.linphone.core.Address;
|
||||
import org.linphone.core.Core;
|
||||
import org.linphone.core.Friend;
|
||||
import org.linphone.core.FriendCapability;
|
||||
import org.linphone.core.FriendList;
|
||||
import org.linphone.core.PresenceBasicStatus;
|
||||
import org.linphone.core.PresenceModel;
|
||||
|
@ -487,4 +488,10 @@ public class LinphoneContact extends AndroidContact
|
|||
deleteFriend();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasFriendCapability(FriendCapability capability) {
|
||||
if (!isFriend()) return false;
|
||||
|
||||
return getFriend().hasCapability(capability);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,16 +33,20 @@ public class SearchContactViewHolder extends RecyclerView.ViewHolder
|
|||
public final ImageView linphoneContact;
|
||||
public final ImageView isSelect;
|
||||
public final RelativeLayout avatarLayout;
|
||||
public final View disabled;
|
||||
|
||||
private final ClickListener mListener;
|
||||
|
||||
public SearchContactViewHolder(View view, ClickListener listener) {
|
||||
super(view);
|
||||
|
||||
name = view.findViewById(R.id.contact_name);
|
||||
address = view.findViewById(R.id.contact_address);
|
||||
linphoneContact = view.findViewById(R.id.contact_linphone);
|
||||
isSelect = view.findViewById(R.id.contact_is_select);
|
||||
avatarLayout = view.findViewById(R.id.avatar_layout);
|
||||
disabled = view.findViewById(R.id.disabled);
|
||||
|
||||
mListener = listener;
|
||||
view.setOnClickListener(this);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.linphone.LinphoneManager;
|
|||
import org.linphone.R;
|
||||
import org.linphone.core.Address;
|
||||
import org.linphone.core.Factory;
|
||||
import org.linphone.core.FriendCapability;
|
||||
import org.linphone.core.PresenceBasicStatus;
|
||||
import org.linphone.core.PresenceModel;
|
||||
import org.linphone.core.ProxyConfig;
|
||||
|
@ -47,20 +48,23 @@ public class SearchContactsAdapter extends RecyclerView.Adapter<SearchContactVie
|
|||
private final ProgressBar mProgressBar;
|
||||
private boolean mOnlySipContact = false;
|
||||
private SearchContactViewHolder.ClickListener mListener;
|
||||
private final boolean mHideSelectionMark;
|
||||
private final boolean mIsOnlyOnePersonSelection;
|
||||
private String mPreviousSearch;
|
||||
private boolean mSecurityEnabled;
|
||||
|
||||
public SearchContactsAdapter(
|
||||
List<ContactAddress> contactsList,
|
||||
ProgressBar pB,
|
||||
SearchContactViewHolder.ClickListener clickListener,
|
||||
boolean hideSelectionMark) {
|
||||
mHideSelectionMark = hideSelectionMark;
|
||||
boolean hideSelectionMark,
|
||||
boolean isSecurityEnabled) {
|
||||
mIsOnlyOnePersonSelection = hideSelectionMark;
|
||||
mListener = clickListener;
|
||||
mProgressBar = pB;
|
||||
setContactsSelectedList(null);
|
||||
setContactsList(contactsList);
|
||||
mPreviousSearch = null;
|
||||
mSecurityEnabled = isSecurityEnabled;
|
||||
}
|
||||
|
||||
public List<ContactAddress> getContacts() {
|
||||
|
@ -71,6 +75,11 @@ public class SearchContactsAdapter extends RecyclerView.Adapter<SearchContactVie
|
|||
mOnlySipContact = enable;
|
||||
}
|
||||
|
||||
public void setSecurityEnabled(boolean enable) {
|
||||
mSecurityEnabled = enable;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public SearchContactViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
@ -113,12 +122,19 @@ public class SearchContactsAdapter extends RecyclerView.Adapter<SearchContactVie
|
|||
holder.name.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
holder.disabled.setVisibility(View.GONE);
|
||||
if (c != null) {
|
||||
if (c.getFullName() == null && c.getFirstName() == null && c.getLastName() == null) {
|
||||
c.setFullName(holder.name.getText().toString());
|
||||
}
|
||||
ContactAvatar.displayAvatar(c, holder.avatarLayout);
|
||||
// TODO get if contact has security capabilities
|
||||
ContactAvatar.displayAvatar(
|
||||
c, c.hasFriendCapability(FriendCapability.LimeX3Dh), holder.avatarLayout);
|
||||
|
||||
if ((!mIsOnlyOnePersonSelection && !c.hasFriendCapability(FriendCapability.GroupChat))
|
||||
|| (mSecurityEnabled && !c.hasFriendCapability(FriendCapability.LimeX3Dh))) {
|
||||
// Disable row, contact doesn't have the required capabilities
|
||||
holder.disabled.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
ContactAvatar.displayAvatar(holder.name.getText().toString(), holder.avatarLayout);
|
||||
}
|
||||
|
@ -137,7 +153,7 @@ public class SearchContactsAdapter extends RecyclerView.Adapter<SearchContactVie
|
|||
} else {
|
||||
holder.isSelect.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
if (mHideSelectionMark) {
|
||||
if (mIsOnlyOnePersonSelection) {
|
||||
holder.isSelect.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,6 +85,16 @@ public class ContactAvatar {
|
|||
}
|
||||
}
|
||||
|
||||
private static void showHasLimeX3dhCapability(View v) {
|
||||
ContactAvatarHolder holder = new ContactAvatarHolder(v);
|
||||
if (holder.securityLevel != null) {
|
||||
holder.securityLevel.setVisibility(View.VISIBLE);
|
||||
holder.securityLevel.setImageResource(R.drawable.security_toogle_icon_green);
|
||||
} else {
|
||||
holder.securityLevel.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setAvatarMask(View v, int resourceId) {
|
||||
ContactAvatarHolder holder = new ContactAvatarHolder(v);
|
||||
holder.avatarMask.setImageResource(resourceId);
|
||||
|
@ -151,6 +161,14 @@ public class ContactAvatar {
|
|||
holder.securityLevel.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
public static void displayAvatar(
|
||||
LinphoneContact contact, boolean hasLimeX3dhCapability, View v) {
|
||||
displayAvatar(contact, v);
|
||||
if (hasLimeX3dhCapability) {
|
||||
showHasLimeX3dhCapability(v);
|
||||
}
|
||||
}
|
||||
|
||||
public static void displayAvatar(
|
||||
LinphoneContact contact, ChatRoomSecurityLevel securityLevel, View v) {
|
||||
displayAvatar(contact, v);
|
||||
|
|
|
@ -1,80 +1,91 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:background="@drawable/list_selector"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
android:padding="5dp">
|
||||
android:layout_height="60dp">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/avatar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center">
|
||||
|
||||
<include layout="@layout/contact_avatar" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="70dp"
|
||||
android:layout_toRightOf="@id/avatar"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/list_selector"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:padding="5dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/contact_name"
|
||||
style="@style/font6"
|
||||
<RelativeLayout
|
||||
android:id="@+id/avatar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center">
|
||||
|
||||
<include layout="@layout/contact_avatar" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="top|left"
|
||||
android:lines="1" />
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="70dp"
|
||||
android:layout_toRightOf="@id/avatar"
|
||||
android:background="@drawable/list_selector"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/contact_address"
|
||||
style="@style/font2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:gravity="bottom|left"
|
||||
android:lines="1" />
|
||||
<TextView
|
||||
android:id="@+id/contact_name"
|
||||
style="@style/font6"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="top|left"
|
||||
android:lines="1" />
|
||||
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/contact_address"
|
||||
style="@style/font2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:gravity="bottom|left"
|
||||
android:lines="1" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_toLeftOf="@+id/contact_is_select">
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_toLeftOf="@+id/contact_is_select">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/contact_linphone"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_gravity="right"
|
||||
android:paddingRight="10dp"
|
||||
android:src="@drawable/linphone_user" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/contact_linphone"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:id="@+id/contact_is_select"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_gravity="right"
|
||||
android:paddingRight="10dp"
|
||||
android:src="@drawable/linphone_user" />
|
||||
android:paddingRight="20dp"
|
||||
android:src="@drawable/check_selected"
|
||||
android:visibility="invisible" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/contact_is_select"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_gravity="right"
|
||||
android:paddingRight="20dp"
|
||||
android:src="@drawable/check_selected"
|
||||
android:visibility="invisible" />
|
||||
|
||||
</RelativeLayout>
|
||||
<View
|
||||
android:id="@+id/disabled"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/contact_disabled"/>
|
||||
</FrameLayout>
|
||||
|
|
|
@ -23,4 +23,5 @@
|
|||
|
||||
<color name="transparent">#00000000</color>
|
||||
<color name="linphone_launcher_icon_background">@color/colorA</color>
|
||||
<color name="contact_disabled">#99ffffff</color>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue