taomenggo init
55
contactkit-ui/build.gradle.kts
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
* Use of this source code is governed by a MIT license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id("com.android.library")
|
||||
kotlin("android")
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk = 33
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 21
|
||||
targetSdk = 33
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
consumerProguardFiles("consumer-rules.pro")
|
||||
buildConfigField("String", "versionName", "\"9.6.2\"")
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
getByName("release") {
|
||||
isMinifyEnabled = true
|
||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||
}
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
}
|
||||
|
||||
sourceSets["main"].res.srcDirs("src/main/res","src/main/res-fun","src/main/res-normal")
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
namespace = "com.netease.yunxin.kit.contactkit.ui"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
|
||||
api("com.netease.yunxin.kit.chat:chatkit:9.6.2")
|
||||
api("com.netease.yunxin.kit.common:common-ui:1.2.0")
|
||||
api("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21")
|
||||
implementation("androidx.appcompat:appcompat:1.4.2")
|
||||
implementation("com.google.android.material:material:1.5.0")
|
||||
implementation("androidx.recyclerview:recyclerview:1.2.1")
|
||||
implementation("com.github.bumptech.glide:glide:4.13.1")
|
||||
implementation("com.google.code.gson:gson:2.9.0")
|
||||
|
||||
}
|
||||
|
||||
0
contactkit-ui/consumer-rules.pro
Normal file
21
contactkit-ui/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.kts.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
119
contactkit-ui/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,119 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.netease.yunxin.kit.contactkit.ui">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<application>
|
||||
<provider
|
||||
android:name="com.netease.yunxin.kit.corekit.startup.InitializationProvider"
|
||||
android:authorities="${applicationId}.xkit-startup"
|
||||
android:exported="false"
|
||||
tools:node="merge">
|
||||
<meta-data
|
||||
android:name="com.netease.yunxin.kit.contactkit.ui.ContactUIService"
|
||||
android:value="xkit.startup" />
|
||||
</provider>
|
||||
|
||||
<activity
|
||||
android:name=".normal.contact.ContactActivity"
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".normal.addfriend.AddFriendActivity"
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
|
||||
<activity
|
||||
android:name=".normal.blacklist.BlackListActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".normal.team.TeamListActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".normal.verify.VerifyListActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".normal.userinfo.UserInfoActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".normal.userinfo.CommentActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".normal.selector.ContactSelectorActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name=".normal.search.GlobalSearchActivity"
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
|
||||
<!-- fun style activity -->
|
||||
<activity
|
||||
android:name=".fun.selector.FunBaseSelectorDataActivity"
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name=".fun.contact.FunContactActivity"
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<!-- <activity-->
|
||||
<!-- android:name=".fun.addfriend.FunAddFriendActivity"-->
|
||||
<!-- android:exported="false"-->
|
||||
<!-- android:screenOrientation="portrait" />-->
|
||||
|
||||
<activity
|
||||
android:name=".fun.blacklist.FunBlackListActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".fun.team.FunTeamListActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".fun.verify.FunVerifyListActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name=".fun.verify.FunVerifyDetailsActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
|
||||
<activity
|
||||
android:name=".fun.userinfo.FunUserInfoActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".fun.userinfo.FunCommentActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
|
||||
<activity
|
||||
android:name=".fun.search.FunSearchActivity"
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui;
|
||||
|
||||
public class ContactConstant {
|
||||
|
||||
public static final String LIB_TAG = "ContactKit-UI";
|
||||
public static final String USER_INFO_KEY = "UserInfo";
|
||||
public static final String REQUEST_CONTACT_SELECTOR_AVATAR = "useravatar";
|
||||
public static final String REQUEST_CONTACT_LAST_FRIENDSBEAN = "lastfiends";
|
||||
public static final String REQUEST_CONTACT_ALL_FRIENDSBEAN = "allfiends";
|
||||
public static final String PATH_FUN_CREATE_GROUP_PAGE = "creategroup";
|
||||
public static final String REQUEST_FUN_CREATE_GROUP_AUTO = "autoinvited";
|
||||
|
||||
public static class SearchViewType {
|
||||
public static final int USER = 1;
|
||||
public static final int TEAM = 2;
|
||||
public static final int GROUP = 3;
|
||||
public static final int TITLE = 4;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui;
|
||||
|
||||
public class ContactKitClient {
|
||||
|
||||
private static ContactUIConfig sContactConfig;
|
||||
|
||||
public static void setContactUIConfig(ContactUIConfig config) {
|
||||
sContactConfig = config;
|
||||
}
|
||||
|
||||
public static ContactUIConfig getContactUIConfig() {
|
||||
return sContactConfig;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui;
|
||||
|
||||
import android.util.SparseArray;
|
||||
import android.view.View;
|
||||
import com.netease.yunxin.kit.contactkit.ui.interfaces.IContactClickListener;
|
||||
import com.netease.yunxin.kit.contactkit.ui.interfaces.IContactSelectorListener;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactEntranceBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListViewAttrs;
|
||||
import java.util.List;
|
||||
|
||||
public class ContactUIConfig {
|
||||
|
||||
public static int INT_DEFAULT_NULL = -1;
|
||||
|
||||
//title config
|
||||
public String title;
|
||||
public Integer titleColor;
|
||||
public boolean showTitleBar = false;
|
||||
public boolean showTitleBarRight2Icon = false;
|
||||
public Integer titleBarRight2Res;
|
||||
public View.OnClickListener titleBarRight2Click;
|
||||
public boolean showTitleBarRightIcon = false;
|
||||
public Integer titleBarRightRes;
|
||||
public View.OnClickListener titleBarRightClick;
|
||||
//page
|
||||
public boolean showHeader = false;
|
||||
public List<ContactEntranceBean> headerData;
|
||||
public ContactListViewAttrs contactAttrs;
|
||||
|
||||
public SparseArray<IContactClickListener> itemClickListeners = new SparseArray<>();
|
||||
public SparseArray<IContactSelectorListener> itemSelectorListeners = new SparseArray<>();
|
||||
|
||||
public IContactFactory viewHolderFactory;
|
||||
|
||||
public IContactViewLayout customLayout;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.netease.yunxin.kit.chatkit.ChatService;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.blacklist.FunBlackListActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.contact.FunContactActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.search.FunSearchActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.team.FunTeamListActivity;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import com.netease.yunxin.kit.corekit.route.XKitRouter;
|
||||
|
||||
@Keep
|
||||
public class ContactUIService extends ChatService {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getServiceName() {
|
||||
return "ContactUIKit";
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getVersionName() {
|
||||
return BuildConfig.versionName;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ChatService create(@NonNull Context context) {
|
||||
//normal
|
||||
// XKitRouter.registerRouter(
|
||||
// RouterConstant.PATH_CONTACT_SELECTOR_PAGE, FunContactSelectorActivity.class);
|
||||
// XKitRouter.registerRouter(RouterConstant.PATH_ADD_FRIEND_PAGE, FunAddFriendActivity.class);
|
||||
// XKitRouter.registerRouter(RouterConstant.PATH_USER_INFO_PAGE, FunUserInfoActivity.class);
|
||||
XKitRouter.registerRouter(RouterConstant.PATH_MY_TEAM_PAGE, FunTeamListActivity.class);
|
||||
XKitRouter.registerRouter(RouterConstant.PATH_MY_BLACK_PAGE, FunBlackListActivity.class);
|
||||
// XKitRouter.registerRouter(RouterConstant.PATH_MY_NOTIFICATION_PAGE, FunVerifyListActivity.class);
|
||||
XKitRouter.registerRouter(RouterConstant.PATH_CONTACT_PAGE, FunContactActivity.class);
|
||||
XKitRouter.registerRouter(RouterConstant.PATH_GLOBAL_SEARCH_PAGE, FunSearchActivity.class);
|
||||
|
||||
//fun
|
||||
// XKitRouter.registerRouter(
|
||||
// RouterConstant.PATH_FUN_CONTACT_SELECTOR_PAGE, FunContactSelectorActivity.class);
|
||||
// XKitRouter.registerRouter(RouterConstant.PATH_FUN_ADD_FRIEND_PAGE, FunAddFriendActivity.class);
|
||||
// XKitRouter.registerRouter(RouterConstant.PATH_FUN_USER_INFO_PAGE, FunUserInfoActivity.class);
|
||||
XKitRouter.registerRouter(RouterConstant.PATH_FUN_MY_TEAM_PAGE, FunTeamListActivity.class);
|
||||
// XKitRouter.registerRouter(RouterConstant.PATH_FUN_MY_BLACK_PAGE, FunBlackListActivity.class);
|
||||
// XKitRouter.registerRouter(
|
||||
// RouterConstant.PATH_FUN_MY_NOTIFICATION_PAGE, FunVerifyListActivity.class);
|
||||
XKitRouter.registerRouter(RouterConstant.PATH_FUN_CONTACT_PAGE, FunContactActivity.class);
|
||||
XKitRouter.registerRouter(RouterConstant.PATH_FUN_GLOBAL_SEARCH_PAGE, FunSearchActivity.class);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FetchCallback;
|
||||
|
||||
public class FetchCallbackImpl<T> implements FetchCallback<T> {
|
||||
|
||||
String data;
|
||||
|
||||
public FetchCallbackImpl(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(@Nullable T param) {}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
public abstract class FragmentBuilder {
|
||||
|
||||
public abstract Fragment build();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
|
||||
public interface IContactFactory {
|
||||
|
||||
//Adapter获取数据对应的ViewType
|
||||
int getItemViewType(BaseContactBean data);
|
||||
|
||||
//创建ViewHolder
|
||||
BaseContactViewHolder createViewHolder(@NonNull ViewGroup parent, int viewType);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui;
|
||||
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactLayout;
|
||||
|
||||
public interface IContactViewLayout {
|
||||
void customizeContactLayout(final ContactLayout layout);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui;
|
||||
|
||||
/** load listener */
|
||||
public interface ILoadListener {
|
||||
|
||||
boolean hasMore();
|
||||
|
||||
void loadMore(Object last);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.activity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.netease.yunxin.kit.common.ui.activities.BaseActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.BaseListActivityLayoutBinding;
|
||||
|
||||
public abstract class BaseListActivity extends BaseActivity {
|
||||
|
||||
protected BaseListActivityLayoutBinding binding;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
binding = BaseListActivityLayoutBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
binding.title.setOnBackIconClickListener(v -> onBackPressed());
|
||||
initView();
|
||||
initData();
|
||||
}
|
||||
|
||||
protected void configViewHolderFactory() {}
|
||||
|
||||
protected abstract void initView();
|
||||
|
||||
protected abstract void initData();
|
||||
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if(null != this.getCurrentFocus()){
|
||||
/**
|
||||
* 点击空白位置 隐藏软键盘
|
||||
*/
|
||||
InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
|
||||
return mInputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
|
||||
}
|
||||
return super .onTouchEvent(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.addfriend;
|
||||
|
||||
import static com.netease.yunxin.kit.contactkit.ui.ContactConstant.LIB_TAG;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.netease.yunxin.kit.alog.ALog;
|
||||
import com.netease.yunxin.kit.chatkit.repo.ContactRepo;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.BaseViewModel;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.FetchResult;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.LoadStatus;
|
||||
import com.netease.yunxin.kit.contactkit.ui.ContactConstant;
|
||||
import com.netease.yunxin.kit.corekit.im.IMKitClient;
|
||||
import com.netease.yunxin.kit.corekit.im.model.UserInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FetchCallback;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AddFriendViewModel extends BaseViewModel {
|
||||
private static final String TAG = "AddFriendViewModel";
|
||||
private final MutableLiveData<FetchResult<UserInfo>> resultLiveData = new MutableLiveData<>();
|
||||
private FetchResult<UserInfo> fetchResult = new FetchResult<>(LoadStatus.Finish);
|
||||
|
||||
public MutableLiveData<FetchResult<UserInfo>> getFetchResult() {
|
||||
return resultLiveData;
|
||||
}
|
||||
|
||||
public void fetchUser(String account) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchUser:" + account);
|
||||
List<String> accountList = new ArrayList<>();
|
||||
accountList.add(account);
|
||||
fetchResult.setStatus(LoadStatus.Loading);
|
||||
resultLiveData.postValue(fetchResult);
|
||||
ContactRepo.fetchUserInfo(
|
||||
accountList,
|
||||
new FetchCallback<List<UserInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable List<UserInfo> param) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchUser,onSuccess:" + (param == null));
|
||||
if (param != null && param.size() > 0) {
|
||||
fetchResult.setStatus(LoadStatus.Success);
|
||||
fetchResult.setData(param.get(0));
|
||||
} else {
|
||||
fetchResult.setData(null);
|
||||
fetchResult.setStatus(LoadStatus.Success);
|
||||
}
|
||||
resultLiveData.postValue(fetchResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchUser,onFailed:" + code);
|
||||
fetchResult.setError(code, "");
|
||||
resultLiveData.postValue(fetchResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchUser,onException");
|
||||
fetchResult.setStatus(LoadStatus.Error);
|
||||
resultLiveData.postValue(fetchResult);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,495 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.addfriend;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.netease.yunxin.kit.common.ui.activities.BaseActivity;
|
||||
import com.netease.yunxin.kit.common.ui.utils.AvatarColor;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.FetchResult;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.LoadStatus;
|
||||
import com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView;
|
||||
import com.netease.yunxin.kit.common.utils.NetworkUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.addfriend.FunAddFriendsBottomDialog;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.userinfo.FunContactBottomConfirmDialog;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactUserInfoBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.userinfo.BaseUserInfoActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.userinfo.UserInfoViewModel;
|
||||
import com.netease.yunxin.kit.contactkit.ui.utils.ColorUtils;
|
||||
import com.netease.yunxin.kit.corekit.im.IMKitClient;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendVerifyType;
|
||||
import com.netease.yunxin.kit.corekit.im.model.UserInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FetchCallback;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import com.netease.yunxin.kit.corekit.route.XKitRouter;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class BaseAddFriendActivity extends BaseActivity {
|
||||
|
||||
protected AddFriendViewModel viewModel;
|
||||
protected UserInfoViewModel userinfoviewModel;
|
||||
protected LinearLayout layoutInputID;
|
||||
private View rootView;
|
||||
protected EditText etAddFriendAccount;
|
||||
protected View ivAddFriendBack;
|
||||
protected View ivFriendClear;
|
||||
protected View ivFriendAccountClear;
|
||||
protected View addFriendEmptyLayout;
|
||||
protected View ivAccountSearch;
|
||||
protected View ivPhoneSearch;
|
||||
|
||||
|
||||
protected EditText etAddFriendPhone;
|
||||
protected TextView tvAddFriendID;
|
||||
protected TextView tvAddFriendPhone;
|
||||
protected RelativeLayout layoutInputPhone;
|
||||
protected LinearLayout layoutUserInfo;
|
||||
protected ContactAvatarView avatarView;
|
||||
protected TextView tvUserName;
|
||||
protected TextView tvUserTips;
|
||||
protected TextView tvUserinfohint;
|
||||
protected boolean isShowId = true;
|
||||
protected TextView tvArea;
|
||||
|
||||
|
||||
protected onBaseAddClickListener onBaseAddClickListener;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
rootView = initViewAndGetRootView(savedInstanceState);
|
||||
checkViews();
|
||||
setContentView(rootView);
|
||||
viewModel = new ViewModelProvider(this).get(AddFriendViewModel.class);
|
||||
userinfoviewModel = new ViewModelProvider(this).get(UserInfoViewModel.class);
|
||||
etAddFriendAccount.setOnEditorActionListener(actionListener);
|
||||
etAddFriendPhone.setOnEditorActionListener(actionListener);
|
||||
//viewModel.getFetchResult().observe(this, this::loadData);
|
||||
ivAddFriendBack.setOnClickListener(v -> this.finish());
|
||||
ivFriendClear.setOnClickListener(v -> etAddFriendPhone.setText(null));
|
||||
ivFriendAccountClear.setOnClickListener(v -> etAddFriendAccount.setText(null));
|
||||
ivAccountSearch.setOnClickListener(view -> {
|
||||
if (onBaseAddClickListener != null && !TextUtils.isEmpty(etAddFriendAccount.getText().toString())) {
|
||||
onBaseAddClickListener.doSearch(etAddFriendAccount.getText().toString());
|
||||
}
|
||||
});
|
||||
ivPhoneSearch.setOnClickListener(view -> {
|
||||
if (onBaseAddClickListener != null && !TextUtils.isEmpty(etAddFriendPhone.getText().toString())) {
|
||||
onBaseAddClickListener.doSearch(etAddFriendPhone.getText().toString());
|
||||
}
|
||||
});
|
||||
etAddFriendAccount.addTextChangedListener(
|
||||
new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
if (TextUtils.isEmpty(s.toString())) {
|
||||
ivFriendAccountClear.setVisibility(View.GONE);
|
||||
layoutUserInfo.setVisibility(View.GONE);
|
||||
showEmptyView(false);
|
||||
} else {
|
||||
ivFriendAccountClear.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
etAddFriendPhone.addTextChangedListener(
|
||||
new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
if (TextUtils.isEmpty(s.toString())) {
|
||||
ivFriendClear.setVisibility(View.GONE);
|
||||
layoutUserInfo.setVisibility(View.GONE);
|
||||
showEmptyView(false);
|
||||
} else {
|
||||
ivFriendClear.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
tvAddFriendID.setOnClickListener(view -> {
|
||||
if (!isShowId) {
|
||||
setShowSearchType(true);
|
||||
}
|
||||
});
|
||||
tvAddFriendPhone.setOnClickListener(view -> {
|
||||
if (isShowId) {
|
||||
setShowSearchType(false);
|
||||
}
|
||||
});
|
||||
|
||||
// tvArea.setOnClickListener(view -> {
|
||||
// if (onBaseAddClickListener != null) {
|
||||
// onBaseAddClickListener.doSearch();
|
||||
// }
|
||||
// });
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void setOnBaseAddClickListener(BaseAddFriendActivity.onBaseAddClickListener onBaseAddClickListener) {
|
||||
this.onBaseAddClickListener = onBaseAddClickListener;
|
||||
}
|
||||
|
||||
public void setShowSearchType(boolean showId) {
|
||||
if (showId) {
|
||||
layoutInputID.setVisibility(View.VISIBLE);
|
||||
layoutInputPhone.setVisibility(View.GONE);
|
||||
addFriendEmptyLayout.setVisibility(View.GONE);
|
||||
layoutUserInfo.setVisibility(View.GONE);
|
||||
tvAddFriendID.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.ic_selected_search), null, null, null);
|
||||
tvAddFriendPhone.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.ic_unselected_search), null, null, null);
|
||||
} else {
|
||||
layoutInputID.setVisibility(View.GONE);
|
||||
layoutInputPhone.setVisibility(View.VISIBLE);
|
||||
addFriendEmptyLayout.setVisibility(View.GONE);
|
||||
layoutUserInfo.setVisibility(View.GONE);
|
||||
tvAddFriendID.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.ic_unselected_search), null, null, null);
|
||||
tvAddFriendPhone.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.ic_selected_search), null, null, null);
|
||||
|
||||
}
|
||||
isShowId = showId;
|
||||
}
|
||||
|
||||
protected abstract View initViewAndGetRootView(Bundle savedInstanceState);
|
||||
|
||||
protected void checkViews() {
|
||||
Objects.requireNonNull(rootView);
|
||||
Objects.requireNonNull(etAddFriendAccount);
|
||||
Objects.requireNonNull(ivAddFriendBack);
|
||||
Objects.requireNonNull(ivFriendClear);
|
||||
Objects.requireNonNull(addFriendEmptyLayout);
|
||||
}
|
||||
|
||||
private final EditText.OnEditorActionListener actionListener =
|
||||
(v, actionId, event) -> {
|
||||
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
|
||||
String accountId = v.getEditableText().toString();
|
||||
if (!TextUtils.isEmpty(accountId)) {
|
||||
if (onBaseAddClickListener != null) {
|
||||
onBaseAddClickListener.doSearch(accountId);
|
||||
}
|
||||
//viewModel.fetchUser(accountId);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
public void loadDataResult(int result, String msg, UserInfo userInfo, boolean isVerify) {
|
||||
if (result == 1) {
|
||||
if (userInfo != null) {
|
||||
showEmptyView(false);
|
||||
ColorUtils.loadAvator(userInfo.getAvatar(), avatarView);
|
||||
// avatarView.setData(userInfo.getAvatar(),
|
||||
// userInfo.getName() == null ? "" : userInfo.getName());
|
||||
tvUserName.setText(userInfo.getName());
|
||||
if (TextUtils.equals(userInfo.getAccount(), IMKitClient.account())) {
|
||||
tvUserinfohint.setText(getString(R.string.fun_contact_searchresult_text));
|
||||
tvUserTips.setVisibility(View.VISIBLE);
|
||||
tvUserTips.setText(getResources().getString(R.string.fun_contact_searchself_txt));
|
||||
tvUserinfohint.setOnClickListener(view -> {
|
||||
// XKitRouter.withKey(RouterConstant.PATH_MINE_INFO_PAGE).withContext(this).navigate();
|
||||
startProfileActivity(userInfo);
|
||||
});
|
||||
} else {
|
||||
userinfoviewModel
|
||||
.getFriendFetchResult()
|
||||
.observe(
|
||||
this,
|
||||
mapFetchResult -> {
|
||||
if (mapFetchResult.getLoadStatus() == LoadStatus.Success) {
|
||||
ContactUserInfoBean userInfoData = mapFetchResult.getData();
|
||||
if (userInfoData.isFriend) {
|
||||
tvUserinfohint.setText(getString(R.string.chat));
|
||||
tvUserTips.setVisibility(View.VISIBLE);
|
||||
tvUserTips.setText(getResources().getString(R.string.fun_contact_searchfriends_txt));
|
||||
tvUserinfohint.setOnClickListener(view -> {
|
||||
XKitRouter.withKey(RouterConstant.PATH_CHAT_P2P_PAGE)
|
||||
.withParam(RouterConstant.CHAT_ID_KRY, userInfoData.data.getAccount())
|
||||
.withContext(this)
|
||||
.navigate();
|
||||
// XKitRouter.withKey(RouterConstant.PATH_USER_INFO_PAGE)
|
||||
// .withContext(this)
|
||||
// .withParam(RouterConstant.KEY_ACCOUNT_ID_KEY, userInfo.getAccount())
|
||||
// .navigate();
|
||||
// startProfileActivity(userInfo);
|
||||
});
|
||||
} else {
|
||||
tvUserinfohint.setText(getString(R.string.fun_contact_searchresult_addtext));
|
||||
tvUserTips.setVisibility(View.GONE);
|
||||
tvUserinfohint.setOnClickListener(view -> {
|
||||
showSendMsgDialog(IMKitClient.getUserInfo(), userInfoData, isVerify);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
Toast.makeText(this, R.string.contact_network_error_tip, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
userinfoviewModel.fetchData(userInfo.getAccount());
|
||||
}
|
||||
layoutUserInfo.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
layoutUserInfo.setVisibility(View.GONE);
|
||||
showEmptyView(true);
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(
|
||||
this, msg, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadData(FetchResult<UserInfo> result) {
|
||||
if (result.getLoadStatus() == LoadStatus.Loading) {
|
||||
//todo show loading progress
|
||||
} else if (result.getLoadStatus() == LoadStatus.Success) {
|
||||
if (result.getData() != null) {
|
||||
showEmptyView(false);
|
||||
UserInfo userInfo = result.getData();
|
||||
avatarView.setData(userInfo.getAvatar(),
|
||||
userInfo.getName() == null ? "" : userInfo.getName());
|
||||
tvUserName.setText(userInfo.getName());
|
||||
if (TextUtils.equals(userInfo.getAccount(), IMKitClient.account())) {
|
||||
tvUserinfohint.setText("主页");
|
||||
tvUserTips.setVisibility(View.VISIBLE);
|
||||
tvUserTips.setText(getResources().getString(R.string.fun_contact_searchself_txt));
|
||||
tvUserinfohint.setOnClickListener(view -> {
|
||||
// XKitRouter.withKey(RouterConstant.PATH_MINE_INFO_PAGE).withContext(this).navigate();
|
||||
startProfileActivity(userInfo);
|
||||
});
|
||||
} else {
|
||||
userinfoviewModel
|
||||
.getFriendFetchResult()
|
||||
.observe(
|
||||
this,
|
||||
mapFetchResult -> {
|
||||
if (mapFetchResult.getLoadStatus() == LoadStatus.Success) {
|
||||
ContactUserInfoBean userInfoData = mapFetchResult.getData();
|
||||
if (userInfoData.isFriend) {
|
||||
tvUserinfohint.setText("主页");
|
||||
tvUserTips.setVisibility(View.VISIBLE);
|
||||
tvUserTips.setText(getResources().getString(R.string.fun_contact_searchfriends_txt));
|
||||
tvUserinfohint.setOnClickListener(view -> {
|
||||
|
||||
// XKitRouter.withKey(RouterConstant.PATH_USER_INFO_PAGE)
|
||||
// .withContext(this)
|
||||
// .withParam(RouterConstant.KEY_ACCOUNT_ID_KEY, userInfo.getAccount())
|
||||
// .navigate();
|
||||
startProfileActivity(userInfo);
|
||||
});
|
||||
} else {
|
||||
tvUserinfohint.setText("添加");
|
||||
tvUserTips.setVisibility(View.GONE);
|
||||
tvUserinfohint.setOnClickListener(view -> {
|
||||
showSendMsgDialog(IMKitClient.getUserInfo(), userInfoData, true);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
Toast.makeText(this, R.string.contact_network_error_tip, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
userinfoviewModel.fetchData(userInfo.getAccount());
|
||||
}
|
||||
layoutUserInfo.setVisibility(View.VISIBLE);
|
||||
|
||||
} else {
|
||||
layoutUserInfo.setVisibility(View.GONE);
|
||||
showEmptyView(true);
|
||||
}
|
||||
|
||||
} else if (result.getLoadStatus() == LoadStatus.Error) {
|
||||
Toast.makeText(
|
||||
this, getResources().getString(R.string.add_friend_search_error), Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
FunAddFriendsBottomDialog addFriendsBottomDialog;
|
||||
|
||||
public void showSendMsgDialog(UserInfo userInfo, ContactUserInfoBean contactUserInfoBean, boolean isVerify) {
|
||||
addFriendsBottomDialog = new FunAddFriendsBottomDialog(this)
|
||||
.configUser(contactUserInfoBean.data.getName(), contactUserInfoBean.data.getAvatar());
|
||||
addFriendsBottomDialog.show(
|
||||
() -> {
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
Toast.makeText(this, R.string.contact_network_error_tip, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
//发送
|
||||
String account = "";
|
||||
if (contactUserInfoBean.data == null) {
|
||||
if (contactUserInfoBean.friendInfo != null) {
|
||||
account = contactUserInfoBean.friendInfo.getAccount();
|
||||
}
|
||||
} else {
|
||||
account = contactUserInfoBean.data.getAccount();
|
||||
}
|
||||
addfriend(account, addFriendsBottomDialog.getVerifyMsg(), isVerify);
|
||||
finish();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void addfriend(String account, String verifymsg, boolean isVerify) {
|
||||
userinfoviewModel.addFriendVerifyMsg(
|
||||
account,
|
||||
verifymsg,
|
||||
isVerify,
|
||||
new FetchCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable Void param) {
|
||||
Toast.makeText(
|
||||
BaseAddFriendActivity.this,
|
||||
getResources().getString(R.string.add_friend_operate_success),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
String tips = getResources().getString(R.string.add_friend_operate_fail);
|
||||
Toast.makeText(
|
||||
BaseAddFriendActivity.this,
|
||||
String.format(tips, String.valueOf(code)),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
String tips = getResources().getString(R.string.add_friend_operate_fail);
|
||||
Toast.makeText(
|
||||
BaseAddFriendActivity.this,
|
||||
String.format(tips, exception.getMessage()),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addFriendNoVerify(String account, String verifymsg) {
|
||||
userinfoviewModel.addFriendVerifyMsg(
|
||||
account,
|
||||
verifymsg,
|
||||
true,
|
||||
new FetchCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable Void param) {
|
||||
Toast.makeText(
|
||||
BaseAddFriendActivity.this,
|
||||
getResources().getString(R.string.add_friend_operate_success),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
String tips = getResources().getString(R.string.add_friend_operate_fail);
|
||||
Toast.makeText(
|
||||
BaseAddFriendActivity.this,
|
||||
String.format(tips, String.valueOf(code)),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
String tips = getResources().getString(R.string.add_friend_operate_fail);
|
||||
Toast.makeText(
|
||||
BaseAddFriendActivity.this,
|
||||
String.format(tips, exception.getMessage()),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void showEmptyView(boolean show) {
|
||||
if (show) {
|
||||
addFriendEmptyLayout.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
addFriendEmptyLayout.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
protected void startProfileActivity(UserInfo userInfo) {
|
||||
if (userInfo == null) {
|
||||
return;
|
||||
}
|
||||
// if (TextUtils.equals(userInfo.getAccount(), IMKitClient.account())) {
|
||||
// XKitRouter.withKey(RouterConstant.PATH_MINE_INFO_PAGE).withContext(this)
|
||||
// .withParam(RouterConstant.KEY_ACCOUNT_ID_KEY, userInfo.getAccount()).navigate();
|
||||
// } else {
|
||||
// XKitRouter.withKey(RouterConstant.PATH_USER_INFO_PAGE)
|
||||
// .withContext(this)
|
||||
// .withParam("uid", userInfo.getAccount())
|
||||
//
|
||||
// .navigate();
|
||||
// }
|
||||
XKitRouter.withKey(RouterConstant.PATH_USER_INFO_PAGE)
|
||||
.withContext(this)
|
||||
.withParam(RouterConstant.KEY_ACCOUNT_ID_KEY, IMKitClient.account())
|
||||
.withParam("userId", userInfo.getAccount())
|
||||
.navigate();
|
||||
}
|
||||
|
||||
|
||||
public interface onBaseAddClickListener {
|
||||
void doSearch(String idOrPhone);
|
||||
|
||||
// String selectorArea();
|
||||
}
|
||||
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if(null != this.getCurrentFocus()){
|
||||
/**
|
||||
* 点击空白位置 隐藏软键盘
|
||||
*/
|
||||
InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
|
||||
return mInputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
|
||||
}
|
||||
return super .onTouchEvent(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.blacklist;
|
||||
|
||||
import static com.netease.yunxin.kit.corekit.im.utils.RouterConstant.REQUEST_CONTACT_SELECTOR_KEY;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.netease.yunxin.kit.alog.ALog;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.FetchResult;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.LoadStatus;
|
||||
import com.netease.yunxin.kit.common.utils.NetworkUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.FetchCallbackImpl;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.activity.BaseListActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.BaseListActivityLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BaseBlackListActivity extends BaseListActivity {
|
||||
|
||||
protected BlackListViewModel viewModel;
|
||||
|
||||
protected ActivityResultLauncher<Intent> blackListLauncher;
|
||||
|
||||
private final String TAG = "BaseBlackListActivity";
|
||||
|
||||
protected void initView() {
|
||||
registerResult();
|
||||
binding.tvTips.setVisibility(View.VISIBLE);
|
||||
binding.tvTips.setText(R.string.black_list_tips);
|
||||
configTitle(binding);
|
||||
configViewHolderFactory();
|
||||
}
|
||||
|
||||
protected void configTitle(BaseListActivityLayoutBinding binding) {
|
||||
}
|
||||
|
||||
private void registerResult() {
|
||||
blackListLauncher =
|
||||
registerForActivityResult(
|
||||
new ActivityResultContracts.StartActivityForResult(),
|
||||
result -> {
|
||||
if (result.getResultCode() == RESULT_OK && result.getData() != null) {
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
Toast.makeText(this, R.string.contact_network_error_tip, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
ArrayList<String> friends =
|
||||
result.getData().getStringArrayListExtra(REQUEST_CONTACT_SELECTOR_KEY);
|
||||
if (friends != null && friends.size() > 0) {
|
||||
for (String account : friends) {
|
||||
ALog.d(TAG, "addBlackList", "account:" + account);
|
||||
viewModel.addBlackOp(
|
||||
account,
|
||||
new FetchCallbackImpl<Void>(account) {
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
String content =
|
||||
String.format(
|
||||
getResources().getString(R.string.add_black_error), account);
|
||||
Toast.makeText(BaseBlackListActivity.this, content, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
String content =
|
||||
String.format(
|
||||
getResources().getString(R.string.add_black_error), account);
|
||||
Toast.makeText(BaseBlackListActivity.this, content, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void initData() {
|
||||
viewModel = new ViewModelProvider(this).get(BlackListViewModel.class);
|
||||
viewModel
|
||||
.getFetchResult()
|
||||
.observe(
|
||||
this,
|
||||
result -> {
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
Toast.makeText(this, R.string.contact_network_error_tip, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
if (result.getLoadStatus() == LoadStatus.Success && result.getData() != null) {
|
||||
ALog.d(TAG, "FetchResult", "Success:" + result.getData().size());
|
||||
binding.contactListView.addContactData(result.getData());
|
||||
}
|
||||
// LoadStatus.Finish respect observer data changed
|
||||
if (result.getLoadStatus() == LoadStatus.Finish && result.getData() != null) {
|
||||
if (result.getType() == FetchResult.FetchType.Add) {
|
||||
ALog.d(TAG, "FetchResult", "Add:" + result.getData().size());
|
||||
binding.contactListView.addContactData(result.getData());
|
||||
} else if (result.getType() == FetchResult.FetchType.Remove) {
|
||||
ALog.d(TAG, "FetchResult", "Remove:" + result.getData().size());
|
||||
binding.contactListView.removeContactData(result.getData());
|
||||
}
|
||||
}
|
||||
List<BaseContactBean> list = binding.contactListView.getAdapter().getDataList();
|
||||
if (list != null && list.size() == 0) {
|
||||
binding.layoutEmpty.setVisibility(View.VISIBLE);
|
||||
binding.contactListView.setVisibility(View.GONE);
|
||||
} else {
|
||||
binding.layoutEmpty.setVisibility(View.GONE);
|
||||
binding.contactListView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
setBtnBackground(false);
|
||||
// if(binding.contactListView.getAdapter().getItemCount()==0){
|
||||
// binding.tvBlackremove.setBackgroundResource(R.drawable.fun_cornor_6d_cccccc);
|
||||
// }else{
|
||||
// binding.tvBlackremove.setBackgroundResource(R.drawable.fun_cornor_6d_6b3689);
|
||||
// }
|
||||
});
|
||||
viewModel.fetchBlackList();
|
||||
}
|
||||
|
||||
public void setBtnBackground(boolean isEnable) {
|
||||
if (isEnable) {
|
||||
binding.tvBlackremove.setBackgroundTintList(null);
|
||||
binding.tvBlackremove.setEnabled(true);
|
||||
} else {
|
||||
binding.tvBlackremove.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.color_6d80ff_alpha70)));
|
||||
binding.tvBlackremove.setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.blacklist;
|
||||
|
||||
import static com.netease.yunxin.kit.contactkit.ui.ContactConstant.LIB_TAG;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import com.netease.yunxin.kit.alog.ALog;
|
||||
import com.netease.yunxin.kit.chatkit.repo.ContactObserverRepo;
|
||||
import com.netease.yunxin.kit.chatkit.repo.ContactRepo;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.BaseViewModel;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.FetchResult;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.LoadStatus;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactBlackListBean;
|
||||
import com.netease.yunxin.kit.corekit.im.model.UserInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FetchCallback;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FriendChangeType;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FriendObserver;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BlackListViewModel extends BaseViewModel {
|
||||
private static final String TAG = "BlackListViewModel";
|
||||
|
||||
private final MutableLiveData<FetchResult<List<ContactBlackListBean>>> resultLiveData =
|
||||
new MutableLiveData<>();
|
||||
private final FetchResult<List<ContactBlackListBean>> fetchResult =
|
||||
new FetchResult<>(LoadStatus.Finish);
|
||||
private final List<ContactBlackListBean> blackList = new ArrayList<>();
|
||||
private final FriendObserver friendObserver;
|
||||
|
||||
public MutableLiveData<FetchResult<List<ContactBlackListBean>>> getFetchResult() {
|
||||
return resultLiveData;
|
||||
}
|
||||
|
||||
public BlackListViewModel() {
|
||||
friendObserver =
|
||||
(friendChangeType, accountList) -> {
|
||||
if (friendChangeType == FriendChangeType.RemoveBlack) {
|
||||
removeBlackData(accountList);
|
||||
}
|
||||
if (friendChangeType == FriendChangeType.AddBlack) {
|
||||
addBlackData(accountList);
|
||||
}
|
||||
};
|
||||
ContactObserverRepo.registerFriendObserver(friendObserver);
|
||||
}
|
||||
|
||||
public void fetchBlackList() {
|
||||
ALog.d(LIB_TAG, TAG, "fetchBlackList");
|
||||
fetchResult.setStatus(LoadStatus.Loading);
|
||||
resultLiveData.postValue(fetchResult);
|
||||
ContactRepo.getBlackList(
|
||||
new FetchCallback<List<UserInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable List<UserInfo> param) {
|
||||
ALog.d(
|
||||
LIB_TAG,
|
||||
TAG,
|
||||
"fetchBlackList,onSuccess:" + (param == null ? "null" : param.size()));
|
||||
blackList.clear();
|
||||
if (param != null && param.size() > 0) {
|
||||
fetchResult.setStatus(LoadStatus.Success);
|
||||
for (UserInfo contactInfo : param) {
|
||||
ContactBlackListBean friendBean = new ContactBlackListBean(contactInfo);
|
||||
friendBean.friendInfo = ContactRepo.getFriend(contactInfo.getAccount());
|
||||
blackList.add(friendBean);
|
||||
}
|
||||
fetchResult.setData(blackList);
|
||||
} else {
|
||||
fetchResult.setData(null);
|
||||
fetchResult.setStatus(LoadStatus.Success);
|
||||
}
|
||||
resultLiveData.postValue(fetchResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchBlackList,onFailed:" + code);
|
||||
fetchResult.setError(code, "");
|
||||
resultLiveData.postValue(fetchResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchBlackList,onException");
|
||||
fetchResult.setError(-1, "");
|
||||
resultLiveData.postValue(fetchResult);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addBlackOp(String account, FetchCallback<Void> callback) {
|
||||
ALog.d(LIB_TAG, TAG, "addBlackOp:" + account);
|
||||
if (!TextUtils.isEmpty(account)) {
|
||||
ContactRepo.addBlackList(account, callback);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeBlackOp(String account, FetchCallback<Void> callback) {
|
||||
ALog.d(LIB_TAG, TAG, "removeBlackOp:" + account);
|
||||
ContactRepo.removeBlackList(account, callback);
|
||||
}
|
||||
|
||||
private void removeBlackData(List<String> accountList) {
|
||||
ALog.d(LIB_TAG, TAG, "removeBlackData:" + (accountList == null ? "null" : accountList.size()));
|
||||
if (accountList == null || accountList.size() < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<ContactBlackListBean> delete = new ArrayList<>();
|
||||
for (String account : accountList) {
|
||||
for (ContactBlackListBean bean : blackList) {
|
||||
if (TextUtils.equals(bean.data.getAccount(), account)) {
|
||||
delete.add(bean);
|
||||
blackList.remove(bean);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//black list match
|
||||
if (accountList.size() == delete.size()) {
|
||||
fetchResult.setFetchType(FetchResult.FetchType.Remove);
|
||||
fetchResult.setData(delete);
|
||||
resultLiveData.setValue(fetchResult);
|
||||
} else {
|
||||
//black list has error,need to fetch
|
||||
fetchBlackList();
|
||||
}
|
||||
}
|
||||
|
||||
private void addBlackData(List<String> accountList) {
|
||||
ALog.d(LIB_TAG, TAG, "addBlackData:" + (accountList == null ? "null" : accountList.size()));
|
||||
if (accountList == null || accountList.size() < 1) {
|
||||
return;
|
||||
}
|
||||
List<ContactBlackListBean> add = new ArrayList<>();
|
||||
ContactRepo.getUserInfo(
|
||||
accountList,
|
||||
new FetchCallback<List<UserInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable List<UserInfo> param) {
|
||||
ALog.d(
|
||||
LIB_TAG, TAG, "addBlackData,onSuccess:" + (param == null ? "null" : param.size()));
|
||||
if (param != null && param.size() > 0) {
|
||||
for (UserInfo contactInfo : param) {
|
||||
ContactBlackListBean blackBean = new ContactBlackListBean(contactInfo);
|
||||
blackBean.friendInfo = ContactRepo.getFriend(contactInfo.getAccount());
|
||||
add.add(blackBean);
|
||||
blackList.add(0, blackBean);
|
||||
}
|
||||
fetchResult.setFetchType(FetchResult.FetchType.Add);
|
||||
fetchResult.setData(add);
|
||||
resultLiveData.setValue(fetchResult);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "addBlackData,onFailed:" + code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "addBlackData,exception");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
super.onCleared();
|
||||
ContactObserverRepo.unregisterFriendObserver(friendObserver);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.contact;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import com.netease.yunxin.kit.common.ui.activities.BaseActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class BaseContactActivity extends BaseActivity {
|
||||
|
||||
private View rootView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
rootView = initViewAndGetRootView(savedInstanceState);
|
||||
checkViews();
|
||||
setContentView(rootView);
|
||||
FragmentManager fragmentManager = getSupportFragmentManager();
|
||||
fragmentManager
|
||||
.beginTransaction()
|
||||
.add(R.id.contact_fragment_container, getContactFragment())
|
||||
.commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
protected abstract View initViewAndGetRootView(Bundle savedInstanceState);
|
||||
|
||||
protected void checkViews() {
|
||||
Objects.requireNonNull(rootView);
|
||||
}
|
||||
|
||||
protected BaseContactFragment getContactFragment() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if(null != this.getCurrentFocus()){
|
||||
/**
|
||||
* 点击空白位置 隐藏软键盘
|
||||
*/
|
||||
InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
|
||||
return mInputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
|
||||
}
|
||||
return super .onTouchEvent(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.contact;
|
||||
|
||||
import static com.netease.yunxin.kit.contactkit.ui.ContactConstant.LIB_TAG;
|
||||
import static com.netease.yunxin.kit.corekit.im.utils.RouterConstant.PATH_ADD_FRIEND_PAGE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import com.netease.yunxin.kit.alog.ALog;
|
||||
import com.netease.yunxin.kit.common.ui.fragments.BaseFragment;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.FetchResult;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.LoadStatus;
|
||||
import com.netease.yunxin.kit.contactkit.ui.ContactKitClient;
|
||||
import com.netease.yunxin.kit.contactkit.ui.ContactUIConfig;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.interfaces.ContactActions;
|
||||
import com.netease.yunxin.kit.contactkit.ui.interfaces.IContactCallback;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactEntranceBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.IViewTypeConstant;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactLayout;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import com.netease.yunxin.kit.corekit.route.XKitRouter;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/** contact page */
|
||||
public abstract class BaseContactFragment extends BaseFragment {
|
||||
private final String TAG = "BaseContactFragment";
|
||||
protected ContactViewModel viewModel;
|
||||
private View rootView;
|
||||
protected ContactLayout contactLayout;
|
||||
protected View emptyView;
|
||||
protected ContactUIConfig contactConfig;
|
||||
protected Observer<FetchResult<List<ContactFriendBean>>> contactObserver;
|
||||
protected Observer<FetchResult<List<ContactFriendBean>>> userInfoObserver;
|
||||
protected IContactCallback contactCallback;
|
||||
protected int headerCount = 0;
|
||||
|
||||
public void setContactConfig(ContactUIConfig config) {
|
||||
contactConfig = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(
|
||||
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
rootView = initViewAndGetRootView(inflater, container, savedInstanceState);
|
||||
checkViews();
|
||||
viewModel = new ViewModelProvider(this).get(ContactViewModel.class);
|
||||
if (ContactKitClient.getContactUIConfig() != null && contactConfig == null) {
|
||||
contactConfig = ContactKitClient.getContactUIConfig();
|
||||
}
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
return rootView;
|
||||
}
|
||||
|
||||
protected abstract View initViewAndGetRootView(
|
||||
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);
|
||||
|
||||
protected void checkViews() {
|
||||
Objects.requireNonNull(rootView);
|
||||
Objects.requireNonNull(contactLayout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
//data observer
|
||||
contactObserver =
|
||||
contactBeansResult -> {
|
||||
if (contactBeansResult.getLoadStatus() == LoadStatus.Success) {
|
||||
ALog.d(LIB_TAG, TAG, "contactObserver, Success");
|
||||
contactLayout
|
||||
.getContactListView()
|
||||
.onFriendDataSourceChanged(contactBeansResult.getData());
|
||||
} else if (contactBeansResult.getLoadStatus() == LoadStatus.Finish) {
|
||||
if (contactBeansResult.getType() == FetchResult.FetchType.Add
|
||||
&& contactBeansResult.getData() != null) {
|
||||
ALog.d(LIB_TAG, TAG, "contactObserver,Add");
|
||||
contactLayout.getContactListView().addFriendData(contactBeansResult.getData());
|
||||
} else if (contactBeansResult.getType() == FetchResult.FetchType.Remove
|
||||
&& contactBeansResult.getData() != null) {
|
||||
ALog.d(LIB_TAG, TAG, "contactObserver,Remove");
|
||||
contactLayout.getContactListView().removeFriendData(contactBeansResult.getData());
|
||||
} else if (contactBeansResult.getType() == FetchResult.FetchType.Update
|
||||
&& contactBeansResult.getData() != null) {
|
||||
ALog.d(LIB_TAG, TAG, "contactObserver,Update");
|
||||
contactLayout.getContactListView().updateFriendData(contactBeansResult.getData());
|
||||
}
|
||||
}
|
||||
if (emptyView != null) {
|
||||
if (contactLayout.getContactListView().getItemCount() - headerCount <= 0) {
|
||||
emptyView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
emptyView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
userInfoObserver =
|
||||
userInfoResult -> {
|
||||
if (userInfoResult.getLoadStatus() == LoadStatus.Finish) {
|
||||
contactLayout.getContactListView().updateFriendData(userInfoResult.getData());
|
||||
}
|
||||
};
|
||||
|
||||
initView();
|
||||
viewModel.getContactLiveData().observeForever(contactObserver);
|
||||
viewModel.getUserInfoLiveData().observeForever(userInfoObserver);
|
||||
viewModel.fetchContactList();
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
loadTitle();
|
||||
initContactAction();
|
||||
loadConfig();
|
||||
}
|
||||
|
||||
private void initContactAction() {
|
||||
ContactActions actions = new ContactActions();
|
||||
//entrance data
|
||||
// loadHeader(actions);
|
||||
|
||||
//contact list
|
||||
loadDefaultContactAction(actions);
|
||||
|
||||
//load contact action
|
||||
loadContactAction(actions);
|
||||
}
|
||||
|
||||
private void loadContactAction(ContactActions actions) {
|
||||
if (contactConfig.itemClickListeners.size() > 0) {
|
||||
for (int index = 0; index < contactConfig.itemClickListeners.size(); index++) {
|
||||
actions.addContactListener(
|
||||
contactConfig.itemClickListeners.keyAt(index),
|
||||
contactConfig.itemClickListeners.valueAt(index));
|
||||
}
|
||||
}
|
||||
|
||||
if (contactConfig.itemSelectorListeners.size() > 0) {
|
||||
for (int index = 0; index < contactConfig.itemSelectorListeners.size(); index++) {
|
||||
actions.addSelectorListener(
|
||||
contactConfig.itemSelectorListeners.keyAt(index),
|
||||
contactConfig.itemSelectorListeners.valueAt(index));
|
||||
}
|
||||
}
|
||||
contactLayout.getContactListView().setContactAction(actions);
|
||||
}
|
||||
|
||||
private void loadConfig() {
|
||||
if (contactConfig != null) {
|
||||
if (contactConfig.viewHolderFactory != null) {
|
||||
contactLayout.getContactListView().setViewHolderFactory(contactConfig.viewHolderFactory);
|
||||
}
|
||||
if (contactConfig.contactAttrs != null) {
|
||||
contactLayout.getContactListView().setViewConfig(contactConfig.contactAttrs);
|
||||
}
|
||||
if (contactConfig.customLayout != null) {
|
||||
contactConfig.customLayout.customizeContactLayout(contactLayout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadDefaultContactAction(ContactActions actions) {
|
||||
actions.addContactListener(
|
||||
IViewTypeConstant.CONTACT_FRIEND,
|
||||
(position, data) -> {
|
||||
FriendInfo friendInfo = ((ContactFriendBean) data).data;
|
||||
XKitRouter.withKey(RouterConstant.PATH_USER_INFO_PAGE)
|
||||
.withContext(requireContext())
|
||||
.withParam(RouterConstant.KEY_ACCOUNT_ID_KEY, friendInfo.getAccount())
|
||||
.navigate();
|
||||
});
|
||||
}
|
||||
|
||||
public int getUnreadCount() {
|
||||
return viewModel.getVerifyCount();
|
||||
}
|
||||
|
||||
public void setContactCallback(IContactCallback contactCallback) {
|
||||
this.contactCallback = contactCallback;
|
||||
if (viewModel != null && contactCallback != null) {
|
||||
this.contactCallback.updateUnreadCount(getUnreadCount());
|
||||
}
|
||||
}
|
||||
|
||||
private void loadHeader(ContactActions actions) {
|
||||
if (contactConfig.showHeader) {
|
||||
if (contactConfig.headerData == null) {
|
||||
List<ContactEntranceBean> entranceBeanList = getContactEntranceList(this.requireContext());
|
||||
headerCount = entranceBeanList.size();
|
||||
viewModel.configVerifyBean(configVerifyBean());
|
||||
for (ContactEntranceBean bean : entranceBeanList) {
|
||||
contactLayout.getContactListView().addContactData(bean);
|
||||
}
|
||||
viewModel
|
||||
.getContactEntranceLiveData()
|
||||
.observe(
|
||||
getViewLifecycleOwner(),
|
||||
contactEntranceBean -> {
|
||||
if (contactCallback != null) {
|
||||
contactCallback.updateUnreadCount(contactEntranceBean.number);
|
||||
}
|
||||
contactLayout.getContactListView().updateContactData(contactEntranceBean);
|
||||
});
|
||||
|
||||
actions.addContactListener(
|
||||
IViewTypeConstant.CONTACT_ACTION_ENTER,
|
||||
(position, data) -> {
|
||||
if (!TextUtils.isEmpty(data.router)) {
|
||||
XKitRouter.withKey(data.router)
|
||||
.withContext(BaseContactFragment.this.requireContext())
|
||||
.navigate();
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
contactLayout.getContactListView().addContactData(contactConfig.headerData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadTitle() {
|
||||
if (contactConfig.showTitleBar) {
|
||||
contactLayout.getTitleBar().setVisibility(View.VISIBLE);
|
||||
if (contactConfig.titleColor != null) {
|
||||
contactLayout.getTitleBar().setTitleColor(contactConfig.titleColor);
|
||||
}
|
||||
if (contactConfig.title != null) {
|
||||
contactLayout.getTitleBar().setTitle(contactConfig.title);
|
||||
} else {
|
||||
contactLayout.getTitleBar().setTitle(getResources().getString(R.string.contact_title));
|
||||
}
|
||||
|
||||
} else {
|
||||
contactLayout.getTitleBar().setVisibility(View.GONE);
|
||||
}
|
||||
if (contactConfig.showTitleBarRight2Icon) {
|
||||
contactLayout.getTitleBar().showRight2ImageView(true);
|
||||
if (contactConfig.titleBarRight2Res != null) {
|
||||
contactLayout.getTitleBar().setRight2ImageRes(contactConfig.titleBarRight2Res);
|
||||
}
|
||||
|
||||
contactLayout
|
||||
.getTitleBar()
|
||||
.setRight2ImageClick(
|
||||
v -> {
|
||||
if (contactConfig.titleBarRight2Click != null) {
|
||||
contactConfig.titleBarRight2Click.onClick(v);
|
||||
} else {
|
||||
XKitRouter.withKey(RouterConstant.PATH_GLOBAL_SEARCH_PAGE)
|
||||
.withContext(requireContext())
|
||||
.navigate();
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
contactLayout.getTitleBar().showRight2ImageView(false);
|
||||
}
|
||||
|
||||
if (contactConfig.showTitleBarRightIcon) {
|
||||
contactLayout.getTitleBar().showRightImageView(true);
|
||||
if (contactConfig.titleBarRightRes != null) {
|
||||
contactLayout.getTitleBar().setRightImageRes(contactConfig.titleBarRightRes);
|
||||
}
|
||||
if (contactConfig.titleBarRightClick != null) {
|
||||
contactLayout.getTitleBar().setRightImageClick(contactConfig.titleBarRightClick);
|
||||
} else {
|
||||
contactLayout
|
||||
.getTitleBar()
|
||||
.setRightImageClick(
|
||||
v ->
|
||||
XKitRouter.withKey(PATH_ADD_FRIEND_PAGE)
|
||||
.withContext(requireContext())
|
||||
.navigate());
|
||||
}
|
||||
|
||||
} else {
|
||||
contactLayout.getTitleBar().showRightImageView(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
ALog.d(LIB_TAG, TAG, "onDestroy");
|
||||
if (viewModel != null) {
|
||||
viewModel.getContactLiveData().removeObserver(contactObserver);
|
||||
}
|
||||
}
|
||||
|
||||
protected List<ContactEntranceBean> getContactEntranceList(Context context) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
protected ContactEntranceBean configVerifyBean() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,394 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.contact;
|
||||
|
||||
import static com.netease.yunxin.kit.contactkit.ui.ContactConstant.LIB_TAG;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.netease.yunxin.kit.alog.ALog;
|
||||
import com.netease.yunxin.kit.chatkit.repo.ContactObserverRepo;
|
||||
import com.netease.yunxin.kit.chatkit.repo.ContactRepo;
|
||||
import com.netease.yunxin.kit.common.ui.utils.ToastX;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.BaseViewModel;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.FetchResult;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.LoadStatus;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactEntranceBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.IViewTypeConstant;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.model.UserInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FetchCallback;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FriendChangeType;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FriendObserver;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.LoginSyncObserver;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.SyncStatus;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.SystemUnreadCountObserver;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.UserInfoObserver;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* contact view model
|
||||
*/
|
||||
public class ContactViewModel extends BaseViewModel {
|
||||
private final String TAG = "ContactViewModel";
|
||||
private final MutableLiveData<FetchResult<List<ContactFriendBean>>> contactLiveData =
|
||||
new MutableLiveData<>();
|
||||
private final FetchResult<List<ContactFriendBean>> fetchResult =
|
||||
new FetchResult<>(LoadStatus.Finish);
|
||||
private final List<ContactFriendBean> contactFriendBeanList = new ArrayList<>();
|
||||
private final MutableLiveData<ContactEntranceBean> contactEntranceLiveData =
|
||||
new MutableLiveData<>();
|
||||
private final MutableLiveData<FetchResult<List<ContactFriendBean>>> userInfoLiveData =
|
||||
new MutableLiveData<>();
|
||||
private ContactEntranceBean verifyBean;
|
||||
private int unreadCount = 0;
|
||||
|
||||
public ContactViewModel() {
|
||||
registerObserver();
|
||||
}
|
||||
|
||||
public LiveData<FetchResult<List<ContactFriendBean>>> getContactLiveData() {
|
||||
return contactLiveData;
|
||||
}
|
||||
|
||||
public LiveData<ContactEntranceBean> getContactEntranceLiveData() {
|
||||
return contactEntranceLiveData;
|
||||
}
|
||||
|
||||
public MutableLiveData<FetchResult<List<ContactFriendBean>>> getUserInfoLiveData() {
|
||||
return userInfoLiveData;
|
||||
}
|
||||
|
||||
public void fetchContactList() {
|
||||
ALog.d(LIB_TAG, TAG, "fetchContactList");
|
||||
ContactRepo.getContactList(
|
||||
new FetchCallback<List<FriendInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable List<FriendInfo> param) {
|
||||
ALog.d(
|
||||
LIB_TAG,
|
||||
TAG,
|
||||
"fetchContactList,onSuccess:" + (param == null ? "null" : param.size()));
|
||||
contactFriendBeanList.clear();
|
||||
if (param != null) {
|
||||
for (FriendInfo info : param) {
|
||||
ContactFriendBean bean = new ContactFriendBean(info);
|
||||
bean.viewType = IViewTypeConstant.CONTACT_FRIEND;
|
||||
contactFriendBeanList.add(bean);
|
||||
}
|
||||
}
|
||||
fetchResult.setStatus(LoadStatus.Success);
|
||||
fetchResult.setData(contactFriendBeanList);
|
||||
contactLiveData.postValue(fetchResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchContactList,onFailed:" + code);
|
||||
fetchResult.setError(code, "");
|
||||
contactLiveData.postValue(fetchResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchContactList,onException");
|
||||
fetchResult.setError(-1, "");
|
||||
contactLiveData.postValue(fetchResult);
|
||||
}
|
||||
});
|
||||
|
||||
ContactRepo.getNotificationUnreadCount(
|
||||
new FetchCallback<Integer>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable Integer count) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchContactList,getNotificationUnreadCount,onSuccess:" + count);
|
||||
updateVerifyNumber(count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchContactList,getNotificationUnreadCount,onFailed:" + code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchContactList,getNotificationUnreadCount,onException");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void registerObserver() {
|
||||
ContactObserverRepo.registerFriendObserver(friendObserver);
|
||||
ContactObserverRepo.registerUserInfoObserver(userInfoObserver);
|
||||
ContactObserverRepo.registerNotificationUnreadCountObserver(unreadCountObserver);
|
||||
ContactObserverRepo.registerLoginSyncObserver(loginSyncObserver);
|
||||
}
|
||||
|
||||
private final UserInfoObserver userInfoObserver =
|
||||
userList -> {
|
||||
ALog.d(LIB_TAG, TAG, "userInfoObserver,userList:" + userList.size());
|
||||
if (userList.size() > 0) {
|
||||
FetchResult<List<ContactFriendBean>> result = new FetchResult<>(LoadStatus.Finish);
|
||||
List<ContactFriendBean> updateBean = new ArrayList<>();
|
||||
for (ContactFriendBean bean : contactFriendBeanList) {
|
||||
for (UserInfo userInfo : userList) {
|
||||
if (TextUtils.equals(userInfo.getAccount(), bean.data.getAccount())) {
|
||||
bean.data.setUserInfo(userInfo);
|
||||
updateBean.add(bean);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
result.setData(updateBean);
|
||||
userInfoLiveData.setValue(result);
|
||||
}
|
||||
};
|
||||
|
||||
private final FriendObserver friendObserver =
|
||||
(friendChangeType, accountList) -> {
|
||||
if (friendChangeType == FriendChangeType.Delete
|
||||
|| friendChangeType == FriendChangeType.AddBlack) {
|
||||
ALog.d(LIB_TAG, TAG, "friendObserver,Delete||AddBlack:" + accountList.size());
|
||||
removeFriend(accountList);
|
||||
return;
|
||||
}
|
||||
if (friendChangeType == FriendChangeType.Update) {
|
||||
ALog.d(LIB_TAG, TAG, "friendObserver,Update:" + accountList.size());
|
||||
updateFriend(accountList);
|
||||
return;
|
||||
}
|
||||
// get new friend account, add or remove
|
||||
List<String> addFriendList = new ArrayList<>();
|
||||
if (friendChangeType == FriendChangeType.RemoveBlack) {
|
||||
for (String account : accountList) {
|
||||
if (ContactRepo.isFriend(account)) {
|
||||
addFriendList.add(account);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (friendChangeType == FriendChangeType.Add) {
|
||||
ALog.d(LIB_TAG, TAG, "friendObserver,Add:" + accountList.size());
|
||||
addFriendList.addAll(accountList);
|
||||
}
|
||||
// fetch friend info and update to view
|
||||
addFriend(addFriendList);
|
||||
};
|
||||
|
||||
private final SystemUnreadCountObserver unreadCountObserver =
|
||||
(count) -> {
|
||||
updateVerifyNumber(count);
|
||||
};
|
||||
|
||||
private void updateVerifyNumber(int count) {
|
||||
ALog.d(LIB_TAG, TAG, "updateVerifyNumber:" + count);
|
||||
if (verifyBean != null) {
|
||||
if (count != unreadCount) {
|
||||
verifyBean.number = count;
|
||||
unreadCount = count;
|
||||
contactEntranceLiveData.postValue(verifyBean);
|
||||
}
|
||||
} else {
|
||||
unreadCount = count;
|
||||
}
|
||||
}
|
||||
|
||||
public int getVerifyCount() {
|
||||
return unreadCount;
|
||||
}
|
||||
|
||||
private final LoginSyncObserver loginSyncObserver =
|
||||
(syncStatus) -> {
|
||||
ALog.d(LIB_TAG, TAG, "loginSyncObserver:" + syncStatus.name());
|
||||
if (syncStatus == SyncStatus.Complete) {
|
||||
fetchContactList();
|
||||
} else if (syncStatus == SyncStatus.BeginSync) {
|
||||
fetchResult.setStatus(LoadStatus.Loading);
|
||||
fetchResult.setData(null);
|
||||
contactLiveData.postValue(fetchResult);
|
||||
}
|
||||
};
|
||||
|
||||
private void removeFriend(List<String> accountList) {
|
||||
ALog.d(LIB_TAG, TAG, "removeFriend:" + (accountList == null ? "null" : accountList.size()));
|
||||
if (accountList == null || accountList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<ContactFriendBean> removeData = new ArrayList<>();
|
||||
for (String account : accountList) {
|
||||
for (ContactFriendBean bean : contactFriendBeanList) {
|
||||
if (TextUtils.equals(account, bean.data.getAccount())) {
|
||||
contactFriendBeanList.remove(bean);
|
||||
removeData.add(bean);
|
||||
ALog.d(LIB_TAG, TAG, "removeFriend:removeData add" + bean.data.getAccount());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ALog.d(
|
||||
LIB_TAG,
|
||||
TAG,
|
||||
"removeFriend:removeData" + (removeData == null ? "null" : removeData.size()));
|
||||
if (!removeData.isEmpty()) {
|
||||
FetchResult<List<ContactFriendBean>> removeResult =
|
||||
new FetchResult<>(FetchResult.FetchType.Remove);
|
||||
removeResult.setData(removeData);
|
||||
contactLiveData.setValue(removeResult);
|
||||
}
|
||||
}
|
||||
|
||||
private void addFriend(List<String> accountList) {
|
||||
ALog.d(LIB_TAG, TAG, "addFriend:" + (accountList == null ? "null" : accountList.size()));
|
||||
assert accountList != null;
|
||||
if (!accountList.isEmpty() && accountList.size() > 0) {
|
||||
ContactRepo.getFriendListWithUserInfo(
|
||||
accountList,
|
||||
new FetchCallback<List<FriendInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable List<FriendInfo> param) {
|
||||
setAddLivieData(param);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "addFriend,onFailed:" + code);
|
||||
ToastX.showShortToast(String.valueOf(code));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "addFriend,onException");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void setAddLivieData(List<FriendInfo> addFriendList) {
|
||||
List<ContactFriendBean> addList = new ArrayList<>();
|
||||
for (FriendInfo friendInfo : addFriendList) {
|
||||
ContactFriendBean bean = new ContactFriendBean(friendInfo);
|
||||
bean.viewType = IViewTypeConstant.CONTACT_FRIEND;
|
||||
if (contactFriendBeanList.contains(bean)) {
|
||||
continue;
|
||||
}
|
||||
contactFriendBeanList.add(bean);
|
||||
ALog.d(LIB_TAG, TAG, "addFriend,add:" + "id=" + friendInfo.getAccount());
|
||||
addList.add(bean);
|
||||
}
|
||||
FetchResult<List<ContactFriendBean>> addResult = new FetchResult<>(FetchResult.FetchType.Add);
|
||||
addResult.setData(addList);
|
||||
contactLiveData.setValue(addResult);
|
||||
}
|
||||
|
||||
private void updateFriend(List<String> accountList) {
|
||||
ALog.d(LIB_TAG, TAG, "updateFriend:" + (accountList == null ? "null" : accountList.size()));
|
||||
ContactRepo.getFriendListWithUserInfo(
|
||||
accountList,
|
||||
new FetchCallback<List<FriendInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable List<FriendInfo> param) {
|
||||
ALog.d(
|
||||
LIB_TAG, TAG, "updateFriend,onSuccess:" + (param == null ? "null" : param.size()));
|
||||
boolean result = setUpdateLiveData(param);
|
||||
//IM SDK 设备登录切换两个账号,都添加统一账号好友并同意,第二个账号收到的是更新好友通知不是添加
|
||||
//更新的时候,发现如果好友不存在,则走添加的逻辑
|
||||
if (!result) {
|
||||
setAddLivieData(param);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "updateFriend,onFailed:" + code);
|
||||
ToastX.showShortToast(String.valueOf(code));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "updateFriend,onException");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean setUpdateLiveData(List<FriendInfo> updateList) {
|
||||
List<ContactFriendBean> updateBean = new ArrayList<>();
|
||||
for (FriendInfo friendInfo : updateList) {
|
||||
if (friendInfo == null) {
|
||||
continue;
|
||||
}
|
||||
for (ContactFriendBean bean : contactFriendBeanList) {
|
||||
if (TextUtils.equals(friendInfo.getAccount(), bean.data.getAccount())) {
|
||||
bean.data = friendInfo;
|
||||
updateBean.add(bean);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (updateBean.size() > 0) {
|
||||
FetchResult<List<ContactFriendBean>> updateResult =
|
||||
new FetchResult<>(FetchResult.FetchType.Update);
|
||||
updateResult.setData(updateBean);
|
||||
contactLiveData.setValue(updateResult);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void configVerifyBean(ContactEntranceBean verifyBean) {
|
||||
this.verifyBean = verifyBean;
|
||||
if (this.verifyBean != null) {
|
||||
this.verifyBean.number = unreadCount;
|
||||
}
|
||||
}
|
||||
|
||||
private List<ContactEntranceBean> getContactEntranceList(Context context) {
|
||||
List<ContactEntranceBean> contactDataList = new ArrayList<>();
|
||||
//verify message
|
||||
verifyBean =
|
||||
new ContactEntranceBean(
|
||||
R.mipmap.ic_contact_verfiy_msg, context.getString(R.string.contact_list_verify_msg));
|
||||
verifyBean.number = unreadCount;
|
||||
verifyBean.router = RouterConstant.PATH_MY_NOTIFICATION_PAGE;
|
||||
//black list
|
||||
ContactEntranceBean blackBean =
|
||||
new ContactEntranceBean(
|
||||
R.mipmap.ic_contact_black_list, context.getString(R.string.contact_list_black_list));
|
||||
blackBean.router = RouterConstant.PATH_MY_BLACK_PAGE;
|
||||
//my group
|
||||
ContactEntranceBean groupBean =
|
||||
new ContactEntranceBean(
|
||||
R.mipmap.ic_contact_my_group, context.getString(R.string.contact_list_my_group));
|
||||
groupBean.router = RouterConstant.PATH_MY_TEAM_PAGE;
|
||||
|
||||
contactDataList.add(verifyBean);
|
||||
contactDataList.add(blackBean);
|
||||
contactDataList.add(groupBean);
|
||||
return contactDataList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void pullContactView() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
super.onCleared();
|
||||
ContactObserverRepo.unregisterFriendObserver(friendObserver);
|
||||
ContactObserverRepo.unregisterUserInfoObserver(userInfoObserver);
|
||||
ContactObserverRepo.unregisterNotificationUnreadCountObserver(unreadCountObserver);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun;
|
||||
|
||||
import android.view.View;
|
||||
import com.netease.yunxin.kit.contactkit.ui.ContactUIConfig;
|
||||
import com.netease.yunxin.kit.contactkit.ui.FragmentBuilder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.contact.FunContactFragment;
|
||||
import com.netease.yunxin.kit.contactkit.ui.interfaces.IContactClickListener;
|
||||
import com.netease.yunxin.kit.contactkit.ui.interfaces.IContactSelectorListener;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactEntranceBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListViewAttrs;
|
||||
import java.util.List;
|
||||
|
||||
public class FunContactFragmentBuilder extends FragmentBuilder {
|
||||
|
||||
ContactUIConfig contactConfig;
|
||||
|
||||
public FunContactFragmentBuilder() {}
|
||||
|
||||
@Override
|
||||
public FunContactFragment build() {
|
||||
FunContactFragment fragment = new FunContactFragment();
|
||||
if (contactConfig != null) {
|
||||
fragment.setContactConfig(contactConfig);
|
||||
}
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public void setContactConfig(ContactUIConfig contactConfig) {
|
||||
this.contactConfig = contactConfig;
|
||||
}
|
||||
|
||||
public FunContactFragmentBuilder setShowTitleBar(boolean show) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.showTitleBar = show;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactFragmentBuilder setTitle(String title) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactFragmentBuilder setTitleColor(int color) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.titleColor = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactFragmentBuilder setShowTitleBarRight2Icon(boolean show) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.showTitleBarRight2Icon = show;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactFragmentBuilder setSearchIcon(int res) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.titleBarRight2Res = res;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactFragmentBuilder setSearchClickListener(View.OnClickListener listener) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.titleBarRight2Click = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactFragmentBuilder setShowMoreIcon(boolean show) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.showTitleBarRightIcon = show;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactFragmentBuilder setMoreIcon(int res) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.titleBarRightRes = res;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactFragmentBuilder setMoreClickListener(View.OnClickListener listener) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.titleBarRightClick = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactFragmentBuilder showHeader(boolean show) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.showHeader = show;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactFragmentBuilder setContactListViewAttar(ContactListViewAttrs attrs) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.contactAttrs = attrs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactFragmentBuilder setHeaderData(List<ContactEntranceBean> data) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.headerData = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactFragmentBuilder setContactClickListener(
|
||||
int type, IContactClickListener contactListener) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.itemClickListeners.put(type, contactListener);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactFragmentBuilder setContactSelection(
|
||||
int type, IContactSelectorListener contactListener) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.itemSelectorListeners.put(type, contactListener);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.addfriend;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.netease.yunxin.kit.alog.ALog;
|
||||
import com.netease.yunxin.kit.common.ui.utils.AvatarColor;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunBottomAddfriendsMessageBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunContactBottomConfirmDialogBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.userinfo.FunContactBottomConfirmDialog;
|
||||
import com.netease.yunxin.kit.contactkit.ui.utils.ColorUtils;
|
||||
|
||||
public class FunAddFriendsBottomDialog extends Dialog {
|
||||
private static final String TAG = "FunBottomConfirmDialog";
|
||||
|
||||
private Runnable confirmRunnable;
|
||||
private FunBottomAddfriendsMessageBinding binding;
|
||||
|
||||
public FunAddFriendsBottomDialog(@NonNull Activity activity) {
|
||||
super(activity, R.style.SelectorFriendsBottomDialogTheme);
|
||||
renderRootView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
// Window window = getWindow();
|
||||
// if (window != null) {
|
||||
// WindowManager.LayoutParams wlp = window.getAttributes();
|
||||
//// wlp.gravity = Gravity.BOTTOM;
|
||||
// wlp.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
|
||||
// wlp.width = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
// wlp.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
// window.setAttributes(wlp);
|
||||
// }
|
||||
setContentView(binding.getRoot());
|
||||
binding.editAddfriendsRemarkmsg.requestFocus();
|
||||
setCanceledOnTouchOutside(true);
|
||||
setCancelable(true);
|
||||
setOnDismissListener(dialog -> confirmRunnable = null);
|
||||
}
|
||||
|
||||
public FunAddFriendsBottomDialog configUser(String name, String avatar) {
|
||||
binding.tvUserName.setText(name);
|
||||
ColorUtils.loadAvator(avatar,binding.cavUserIcon);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* render page
|
||||
*/
|
||||
private void renderRootView() {
|
||||
binding = FunBottomAddfriendsMessageBinding.inflate(getLayoutInflater());
|
||||
binding.tvAddfriendsSend.setOnClickListener(
|
||||
v -> {
|
||||
if (confirmRunnable != null) {
|
||||
confirmRunnable.run();
|
||||
}
|
||||
dismiss();
|
||||
});
|
||||
binding.viewCloseclick.setOnClickListener(v -> dismiss());
|
||||
}
|
||||
|
||||
public String getVerifyMsg() {
|
||||
return binding.editAddfriendsVerifymsg.getText().toString();
|
||||
}
|
||||
|
||||
public String getRemarksMsg() {
|
||||
return binding.editAddfriendsRemarkmsg.getText().toString();
|
||||
}
|
||||
|
||||
public void show(Runnable confirmRunnable) {
|
||||
if (isShowing()) {
|
||||
return;
|
||||
}
|
||||
this.confirmRunnable = confirmRunnable;
|
||||
try {
|
||||
super.show();
|
||||
} catch (Throwable throwable) {
|
||||
ALog.e(TAG, "show FunBottomConfirmDialog", throwable);
|
||||
}
|
||||
}
|
||||
|
||||
public void dismiss() {
|
||||
if (!isShowing()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
super.dismiss();
|
||||
} catch (Throwable throwable) {
|
||||
ALog.e(TAG, "dismiss FunBottomConfirmDialog", throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.blacklist;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.netease.yunxin.kit.common.utils.NetworkUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.blacklist.BaseBlackListActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.BaseListActivityLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.view.FunContactViewHolderFactory;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.view.viewholder.FunBlackListViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactBlackListBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.IViewTypeConstant;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FetchCallback;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import com.netease.yunxin.kit.corekit.route.XKitRouter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@Deprecated
|
||||
public class FunBlackListActivity extends BaseBlackListActivity {
|
||||
|
||||
private FunBlackListViewHolder viewHolder;
|
||||
private List<ContactBlackListBean> listBlackUserInfo = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
changeStatusBarColor(R.color.color_white);
|
||||
binding.heimindanTv.setVisibility(View.VISIBLE);
|
||||
binding.tvBlackremove.setVisibility(View.VISIBLE);
|
||||
binding.tvBlackremove.setOnClickListener(view -> {
|
||||
if (listBlackUserInfo.size() > 0) {
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
Toast.makeText(
|
||||
FunBlackListActivity.this,
|
||||
R.string.contact_network_error_tip,
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
for (ContactBlackListBean data : listBlackUserInfo) {
|
||||
remove(data);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void remove(ContactBlackListBean data) {
|
||||
viewModel.removeBlackOp(
|
||||
data.data.getAccount(),
|
||||
new FetchCallback<Void>() {
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
Toast.makeText(
|
||||
FunBlackListActivity.this,
|
||||
getText(R.string.remove_black_fail),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
Toast.makeText(
|
||||
FunBlackListActivity.this,
|
||||
getText(R.string.remove_black_fail),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(@Nullable Void param) {
|
||||
binding.contactListView.removeContactData(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void configTitle(BaseListActivityLayoutBinding binding) {
|
||||
binding
|
||||
.title
|
||||
.setTitle(R.string.black_list)
|
||||
// .setActionImg(R.mipmap.ic_title_bar_more)
|
||||
.setActionListener(
|
||||
v -> {
|
||||
XKitRouter.withKey(RouterConstant.PATH_FUN_CONTACT_SELECTOR_PAGE)
|
||||
.withContext(this)
|
||||
.navigate(blackListLauncher);
|
||||
});
|
||||
binding.title.getTitleTextView().setTextSize(17);
|
||||
binding.title.getTitleTextView().setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
|
||||
binding.title.setBackgroundResource(R.color.color_white);
|
||||
}
|
||||
|
||||
public void setBlackRemoveBg() {
|
||||
if (listBlackUserInfo.size() > 0) {
|
||||
binding.tvBlackremove.setBackgroundResource(R.drawable.fun_cornor_12d_fe6881);
|
||||
} else {
|
||||
binding.tvBlackremove.setBackgroundResource(R.drawable.fun_cornor_6d_cccccc);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configViewHolderFactory() {
|
||||
binding.contactListView.setViewHolderFactory(
|
||||
new FunContactViewHolderFactory() {
|
||||
@Override
|
||||
protected BaseContactViewHolder getCustomViewHolder(ViewGroup view, int viewType) {
|
||||
if (viewType == IViewTypeConstant.CONTACT_BLACK_LIST) {
|
||||
viewHolder = new FunBlackListViewHolder(view);
|
||||
viewHolder.setItemCheckedListener((data, isCheck) -> {
|
||||
if (isCheck) {
|
||||
listBlackUserInfo.add(data);
|
||||
} else {
|
||||
listBlackUserInfo.remove(data);
|
||||
}
|
||||
setBlackRemoveBg();
|
||||
});
|
||||
// viewHolder.setRelieveListener(
|
||||
// data -> {
|
||||
// if (!NetworkUtils.isConnected()) {
|
||||
// Toast.makeText(
|
||||
// FunBlackListActivity.this,
|
||||
// R.string.contact_network_error_tip,
|
||||
// Toast.LENGTH_SHORT)
|
||||
// .show();
|
||||
// return;
|
||||
// }
|
||||
// viewModel.removeBlackOp(
|
||||
// data.data.getAccount(),
|
||||
// new FetchCallback<Void>() {
|
||||
//
|
||||
// @Override
|
||||
// public void onException(@Nullable Throwable exception) {
|
||||
// Toast.makeText(
|
||||
// FunBlackListActivity.this,
|
||||
// getText(R.string.remove_black_fail),
|
||||
// Toast.LENGTH_SHORT)
|
||||
// .show();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onFailed(int code) {
|
||||
// Toast.makeText(
|
||||
// FunBlackListActivity.this,
|
||||
// getText(R.string.remove_black_fail),
|
||||
// Toast.LENGTH_SHORT)
|
||||
// .show();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onSuccess(@Nullable Void param) {
|
||||
// binding.contactListView.removeContactData(data);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
return viewHolder;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.contact;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import com.netease.yunxin.kit.contactkit.ui.contact.BaseContactActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.contact.BaseContactFragment;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunContactActivityBinding;
|
||||
|
||||
public class FunContactActivity extends BaseContactActivity {
|
||||
|
||||
@Override
|
||||
protected View initViewAndGetRootView(Bundle savedInstanceState) {
|
||||
FunContactActivityBinding viewBinding =
|
||||
FunContactActivityBinding.inflate(LayoutInflater.from(this));
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
protected BaseContactFragment getContactFragment() {
|
||||
return new FunContactFragment();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.contact;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.view.FunContactViewHolderFactory;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
|
||||
public class FunContactDefaultFactory extends FunContactViewHolderFactory {
|
||||
@Override
|
||||
protected BaseContactViewHolder getCustomViewHolder(ViewGroup view, int viewType) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.contact;
|
||||
|
||||
import static com.netease.yunxin.kit.corekit.im.utils.RouterConstant.PATH_FUN_ADD_FRIEND_PAGE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.contact.BaseContactFragment;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunContactFragmentBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunContactTopSearchViewBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.interfaces.ContactActions;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactEntranceBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.IViewTypeConstant;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListViewAttrs;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import com.netease.yunxin.kit.corekit.route.XKitRouter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* contact page
|
||||
*/
|
||||
public class FunContactFragment extends BaseContactFragment {
|
||||
private final String TAG = "FunContactFragment";
|
||||
private FunContactFragmentBinding viewBinding;
|
||||
private ContactEntranceBean verifyBean;
|
||||
|
||||
@Override
|
||||
protected View initViewAndGetRootView(
|
||||
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
viewBinding = FunContactFragmentBinding.inflate(inflater, container, false);
|
||||
contactLayout = viewBinding.contactLayout;
|
||||
contactLayout
|
||||
.getContactListView()
|
||||
.getDecoration()
|
||||
.setTitleAlignBottom(true)
|
||||
.setShowTagOff(false)
|
||||
.setIndexDecorationBg(getResources().getColor(R.color.title_transfer))
|
||||
.setColorTitleBottomLine(getResources().getColor(R.color.title_transfer));
|
||||
// loadconfig();
|
||||
FunContactDefaultFactory funContactDefaultFactory = new FunContactDefaultFactory();
|
||||
funContactDefaultFactory.setCenter(true);
|
||||
contactLayout.getContactListView().setViewHolderFactory(funContactDefaultFactory);
|
||||
contactLayout
|
||||
.getContactListView()
|
||||
.configIndexTextBGColor(getResources().getColor(R.color.color_58be6b));
|
||||
contactLayout.getDivideLineForTitle().setVisibility(View.GONE);
|
||||
// addTopView(inflater, contactLayout.getBodyTopLayout());
|
||||
emptyView = viewBinding.emptyLayout;
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
private void loadconfig() {
|
||||
ContactListViewAttrs attrs = new ContactListViewAttrs();
|
||||
attrs.setShowIndexBar(true);
|
||||
attrs.setShowPinTop(true);
|
||||
contactLayout.getContactListView().setViewConfig(attrs);
|
||||
}
|
||||
|
||||
private void addTopView(LayoutInflater inflater, ViewGroup topGroup) {
|
||||
topGroup.setBackgroundResource(R.color.color_ededed);
|
||||
FunContactTopSearchViewBinding topSearchViewBinding =
|
||||
FunContactTopSearchViewBinding.inflate(inflater, topGroup, true);
|
||||
topSearchViewBinding
|
||||
.getRoot()
|
||||
.setOnClickListener(
|
||||
v -> {
|
||||
if (contactConfig.titleBarRight2Click != null) {
|
||||
contactConfig.titleBarRight2Click.onClick(v);
|
||||
} else {
|
||||
XKitRouter.withKey(RouterConstant.PATH_FUN_GLOBAL_SEARCH_PAGE)
|
||||
.withContext(requireContext())
|
||||
.navigate();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadDefaultContactAction(ContactActions actions) {
|
||||
actions.addContactListener(
|
||||
IViewTypeConstant.CONTACT_FRIEND,
|
||||
(position, data) -> {
|
||||
FriendInfo friendInfo = ((ContactFriendBean) data).data;
|
||||
XKitRouter.withKey(RouterConstant.PATH_FUN_CHAT_P2P_PAGE)
|
||||
.withParam(RouterConstant.CHAT_ID_KRY, friendInfo.getAccount())
|
||||
.withContext(requireActivity())
|
||||
.navigate();
|
||||
// XKitRouter.withKey(RouterConstant.PATH_FUN_USER_INFO_PAGE)
|
||||
// .withContext(requireContext())
|
||||
// .withParam(RouterConstant.KEY_ACCOUNT_ID_KEY, friendInfo.getAccount())
|
||||
// .navigate();
|
||||
});
|
||||
}
|
||||
|
||||
protected void loadTitle() {
|
||||
if (contactConfig.showTitleBar) {
|
||||
viewBinding.contactLayout.getTitleBar().setTitleBgRes(R.color.color_ededed);
|
||||
viewBinding.contactLayout.getTitleBar().getTitleTextView().setVisibility(View.GONE);
|
||||
viewBinding
|
||||
.contactLayout
|
||||
.getTitleBar()
|
||||
.getCenterTitleTextView()
|
||||
.setTextColor(getResources().getColor(R.color.title_color));
|
||||
viewBinding.contactLayout.getTitleBar().getCenterTitleTextView().setTextSize(17);
|
||||
viewBinding.contactLayout.getTitleBar().setVisibility(View.VISIBLE);
|
||||
if (contactConfig.titleColor != null) {
|
||||
viewBinding
|
||||
.contactLayout
|
||||
.getTitleBar()
|
||||
.getCenterTitleTextView()
|
||||
.setTextColor(contactConfig.titleColor);
|
||||
}
|
||||
if (contactConfig.title != null) {
|
||||
viewBinding
|
||||
.contactLayout
|
||||
.getTitleBar()
|
||||
.getCenterTitleTextView()
|
||||
.setText(contactConfig.title);
|
||||
} else {
|
||||
viewBinding
|
||||
.contactLayout
|
||||
.getTitleBar()
|
||||
.getCenterTitleTextView()
|
||||
.setText(getResources().getString(R.string.contact_title));
|
||||
}
|
||||
} else {
|
||||
viewBinding.contactLayout.getTitleBar().setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
viewBinding.contactLayout.getTitleBar().showRight2ImageView(false);
|
||||
|
||||
if (contactConfig.showTitleBarRightIcon) {
|
||||
viewBinding.contactLayout.getTitleBar().showRightImageView(true);
|
||||
if (contactConfig.titleBarRightRes != null) {
|
||||
viewBinding.contactLayout.getTitleBar().setRightImageRes(contactConfig.titleBarRightRes);
|
||||
} else {
|
||||
viewBinding
|
||||
.contactLayout
|
||||
.getTitleBar()
|
||||
.setRightImageRes(R.drawable.fun_ic_contact_add_friend);
|
||||
}
|
||||
if (contactConfig.titleBarRightClick != null) {
|
||||
viewBinding
|
||||
.contactLayout
|
||||
.getTitleBar()
|
||||
.setRightImageClick(contactConfig.titleBarRightClick);
|
||||
} else {
|
||||
viewBinding
|
||||
.contactLayout
|
||||
.getTitleBar()
|
||||
.setRightImageClick(
|
||||
v ->
|
||||
XKitRouter.withKey(PATH_FUN_ADD_FRIEND_PAGE)
|
||||
.withContext(requireContext())
|
||||
.navigate());
|
||||
}
|
||||
|
||||
} else {
|
||||
viewBinding.contactLayout.getTitleBar().showRightImageView(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ContactEntranceBean> getContactEntranceList(Context context) {
|
||||
List<ContactEntranceBean> contactDataList = new ArrayList<>();
|
||||
//verify message
|
||||
verifyBean =
|
||||
new ContactEntranceBean(
|
||||
R.mipmap.fun_ic_contact_verfiy_msg,
|
||||
context.getString(R.string.contact_list_verify_msg));
|
||||
verifyBean.router = RouterConstant.PATH_FUN_MY_NOTIFICATION_PAGE;
|
||||
verifyBean.showRightArrow = false;
|
||||
//black list
|
||||
ContactEntranceBean blackBean =
|
||||
new ContactEntranceBean(
|
||||
R.mipmap.fun_ic_contact_black_list,
|
||||
context.getString(R.string.contact_list_black_list));
|
||||
blackBean.router = RouterConstant.PATH_FUN_MY_BLACK_PAGE;
|
||||
blackBean.showRightArrow = false;
|
||||
//my group
|
||||
ContactEntranceBean groupBean =
|
||||
new ContactEntranceBean(
|
||||
R.mipmap.fun_ic_contact_my_group, context.getString(R.string.contact_list_my_group));
|
||||
groupBean.router = RouterConstant.PATH_FUN_MY_TEAM_PAGE;
|
||||
groupBean.showRightArrow = false;
|
||||
|
||||
contactDataList.add(verifyBean);
|
||||
contactDataList.add(blackBean);
|
||||
contactDataList.add(groupBean);
|
||||
return contactDataList;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ContactEntranceBean configVerifyBean() {
|
||||
return verifyBean;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.search;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.netease.yunxin.kit.common.utils.SizeUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunSearchActivityBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.search.page.BaseSearchActivity;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
|
||||
public class FunSearchActivity extends BaseSearchActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setStatusBarColor(getResources().getColor(R.color.color_fcfcfc));
|
||||
getWindow().setNavigationBarColor(getResources().getColor(R.color.color_white));
|
||||
// changeStatusBarColor(R.color.fun_contact_page_bg_color);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View initViewAndGetRootView() {
|
||||
FunSearchActivityBinding viewBinding = FunSearchActivityBinding.inflate(getLayoutInflater());
|
||||
searchRv = viewBinding.rvSearch;
|
||||
clearView = viewBinding.ivClear;
|
||||
emptyView = viewBinding.emptyLl;
|
||||
searchEditText = viewBinding.etSearch;
|
||||
backView = viewBinding.funTitleBar.getBackImageView();
|
||||
searchRv.addItemDecoration(getItemDecoration());
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindView() {
|
||||
super.bindView();
|
||||
searchAdapter.setViewHolderFactory(new FunSearchViewHolderFactory());
|
||||
routerFriend = RouterConstant.PATH_FUN_CHAT_P2P_PAGE;
|
||||
routerTeam = RouterConstant.PATH_FUN_CHAT_TEAM_PAGE;
|
||||
}
|
||||
|
||||
public RecyclerView.ItemDecoration getItemDecoration() {
|
||||
return new RecyclerView.ItemDecoration() {
|
||||
final int topPadding = SizeUtils.dp2px(0.5f);
|
||||
final int indent = SizeUtils.dp2px(16);
|
||||
|
||||
@Override
|
||||
public void onDrawOver(
|
||||
@NonNull Canvas canvas, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
|
||||
int left = parent.getPaddingLeft() + indent;
|
||||
int right = parent.getWidth() - parent.getPaddingRight();
|
||||
|
||||
int childCount = parent.getChildCount();
|
||||
for (int i = 0; i < childCount - 1; i++) {
|
||||
View child = parent.getChildAt(i);
|
||||
|
||||
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
|
||||
|
||||
int top = child.getBottom() + params.bottomMargin;
|
||||
int bottom = top + topPadding;
|
||||
|
||||
Paint paint = new Paint();
|
||||
paint.setColor(Color.LTGRAY);
|
||||
canvas.drawRect(left, top, right, bottom, paint);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.search;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.BaseViewHolder;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.IViewHolderFactory;
|
||||
import com.netease.yunxin.kit.contactkit.ui.ContactConstant;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunSearchTitleViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunSearchUserViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.search.viewholder.FunSearchFriendViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.search.viewholder.FunSearchTeamViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.search.viewholder.FunTitleViewHolder;
|
||||
|
||||
/** search result list view holder factory */
|
||||
public class FunSearchViewHolderFactory implements IViewHolderFactory {
|
||||
|
||||
@Override
|
||||
public BaseViewHolder createViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
||||
if (viewType == ContactConstant.SearchViewType.TITLE) { //title view
|
||||
return new FunTitleViewHolder(
|
||||
FunSearchTitleViewHolderBinding.inflate(
|
||||
LayoutInflater.from(parent.getContext()), parent, false));
|
||||
} else if (viewType == ContactConstant.SearchViewType.USER) { // friend view
|
||||
return new FunSearchFriendViewHolder(
|
||||
FunSearchUserViewHolderBinding.inflate(
|
||||
LayoutInflater.from(parent.getContext()), parent, false));
|
||||
} else if (viewType == ContactConstant.SearchViewType.TEAM) { //team view
|
||||
return new FunSearchTeamViewHolder(
|
||||
FunSearchUserViewHolderBinding.inflate(
|
||||
LayoutInflater.from(parent.getContext()), parent, false));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.search.viewholder;
|
||||
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.netease.nimlib.sdk.search.model.RecordHitInfo;
|
||||
import com.netease.yunxin.kit.chatkit.model.FriendSearchInfo;
|
||||
import com.netease.yunxin.kit.chatkit.model.HitType;
|
||||
import com.netease.yunxin.kit.common.ui.utils.AvatarColor;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.BaseViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunSearchUserViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.SearchFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.utils.ColorUtils;
|
||||
|
||||
public class FunSearchFriendViewHolder extends BaseViewHolder<SearchFriendBean> {
|
||||
private FriendSearchInfo friendInfo;
|
||||
private FunSearchUserViewHolderBinding viewBinding;
|
||||
|
||||
public FunSearchFriendViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
public FunSearchFriendViewHolder(@NonNull FunSearchUserViewHolderBinding viewBinding) {
|
||||
this(viewBinding.getRoot());
|
||||
this.viewBinding = viewBinding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindData(SearchFriendBean data, int position) {
|
||||
friendInfo = data.friendSearchInfo;
|
||||
if (friendInfo != null) {
|
||||
ColorUtils.loadAvator(friendInfo.getFriendInfo().getAvatar(),viewBinding.cavUserIcon);
|
||||
// viewBinding.cavUserIcon.setData(
|
||||
// friendInfo.getFriendInfo().getAvatar(),
|
||||
// friendInfo.getFriendInfo().getName(),
|
||||
// AvatarColor.avatarColor(friendInfo.getFriendInfo().getAccount()));
|
||||
if (friendInfo.getHitType() == HitType.Alias) {
|
||||
viewBinding.nickTv.setText(
|
||||
getSelectSpanText(friendInfo.getFriendInfo().getAlias(), friendInfo.getHitInfo()));
|
||||
viewBinding.nameTv.setVisibility(View.GONE);
|
||||
} else if (friendInfo.getHitType() == HitType.UserName) {
|
||||
|
||||
if (!TextUtils.isEmpty(friendInfo.getFriendInfo().getAlias())) {
|
||||
viewBinding.nickTv.setText(friendInfo.getFriendInfo().getAlias());
|
||||
viewBinding.nickTv.setVisibility(View.VISIBLE);
|
||||
viewBinding.nameTv.setText(
|
||||
getSelectSpanText(
|
||||
friendInfo.getFriendInfo().getUserInfo().getName(), friendInfo.getHitInfo()));
|
||||
viewBinding.nameTv.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
viewBinding.nickTv.setText(
|
||||
getSelectSpanText(
|
||||
friendInfo.getFriendInfo().getUserInfo().getName(), friendInfo.getHitInfo()));
|
||||
viewBinding.nickTv.setVisibility(View.VISIBLE);
|
||||
viewBinding.nameTv.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
viewBinding.nickTv.setVisibility(View.VISIBLE);
|
||||
if (!TextUtils.isEmpty(friendInfo.getFriendInfo().getAlias())) {
|
||||
viewBinding.nickTv.setText(friendInfo.getFriendInfo().getAlias());
|
||||
viewBinding.nameTv.setText(
|
||||
getSelectSpanText(friendInfo.getFriendInfo().getAccount(), friendInfo.getHitInfo()));
|
||||
viewBinding.nameTv.setVisibility(View.VISIBLE);
|
||||
} else if (!TextUtils.isEmpty(friendInfo.getFriendInfo().getUserInfo().getName())) {
|
||||
viewBinding.nickTv.setText(friendInfo.getFriendInfo().getUserInfo().getName());
|
||||
viewBinding.nameTv.setText(
|
||||
getSelectSpanText(friendInfo.getFriendInfo().getAccount(), friendInfo.getHitInfo()));
|
||||
viewBinding.nameTv.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
viewBinding.nickTv.setText(
|
||||
getSelectSpanText(friendInfo.getFriendInfo().getAccount(), friendInfo.getHitInfo()));
|
||||
viewBinding.nameTv.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
viewBinding.getRoot().setOnClickListener(v -> itemListener.onClick(v, data, position));
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
private SpannableString getSelectSpanText(String text, RecordHitInfo hitInfo) {
|
||||
SpannableString spannable = new SpannableString(text);
|
||||
if (hitInfo != null) {
|
||||
spannable.setSpan(
|
||||
new ForegroundColorSpan(
|
||||
viewBinding
|
||||
.getRoot()
|
||||
.getContext()
|
||||
.getResources()
|
||||
.getColor(R.color.fun_contact_search_hit_text_color)),
|
||||
hitInfo.start,
|
||||
hitInfo.end,
|
||||
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
return spannable;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.search.viewholder;
|
||||
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.netease.nimlib.sdk.search.model.RecordHitInfo;
|
||||
import com.netease.yunxin.kit.chatkit.model.TeamSearchInfo;
|
||||
import com.netease.yunxin.kit.common.ui.utils.AvatarColor;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.BaseViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunSearchUserViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.SearchTeamBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.utils.ColorUtils;
|
||||
|
||||
public class FunSearchTeamViewHolder extends BaseViewHolder<SearchTeamBean> {
|
||||
|
||||
private FunSearchUserViewHolderBinding viewBinding;
|
||||
private TeamSearchInfo searchInfo;
|
||||
|
||||
public FunSearchTeamViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
public FunSearchTeamViewHolder(@NonNull FunSearchUserViewHolderBinding viewBinding) {
|
||||
this(viewBinding.getRoot());
|
||||
this.viewBinding = viewBinding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindData(SearchTeamBean data, int position) {
|
||||
if (data != null) {
|
||||
searchInfo = data.teamSearchInfo;
|
||||
ColorUtils.loadGroupAvator(searchInfo.getTeam().getIcon(), viewBinding.cavUserIcon);
|
||||
// if(TextUtils.isEmpty(searchInfo.getTeam().getIcon())){
|
||||
// viewBinding.cavUserIcon.setData(R.mipmap.ic_group_defaulthead, searchInfo.getTeam().getName());
|
||||
// }else{
|
||||
// viewBinding.cavUserIcon.setData(
|
||||
// searchInfo.getTeam().getIcon(),
|
||||
// searchInfo.getTeam().getName(),
|
||||
// AvatarColor.avatarColor(searchInfo.getTeam().getId()));
|
||||
// }
|
||||
viewBinding.nickTv.setText(
|
||||
getSelectSpanText(searchInfo.getTeam().getName(), searchInfo.getHitInfo()));
|
||||
viewBinding.nickTv.setVisibility(View.VISIBLE);
|
||||
viewBinding.nameTv.setVisibility(View.GONE);
|
||||
viewBinding.getRoot().setOnClickListener(v -> itemListener.onClick(v, data, position));
|
||||
}
|
||||
}
|
||||
|
||||
private SpannableString getSelectSpanText(String text, RecordHitInfo hitInfo) {
|
||||
SpannableString spannable = new SpannableString(text);
|
||||
if (hitInfo != null) {
|
||||
spannable.setSpan(
|
||||
new ForegroundColorSpan(
|
||||
viewBinding
|
||||
.getRoot()
|
||||
.getContext()
|
||||
.getResources()
|
||||
.getColor(R.color.fun_contact_search_hit_text_color)),
|
||||
hitInfo.start,
|
||||
hitInfo.end,
|
||||
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
return spannable;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.search.viewholder;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.BaseViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunSearchTitleViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.SearchTitleBean;
|
||||
|
||||
public class FunTitleViewHolder extends BaseViewHolder<SearchTitleBean> {
|
||||
|
||||
private FunSearchTitleViewHolderBinding viewBinding;
|
||||
|
||||
public FunTitleViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
public FunTitleViewHolder(@NonNull FunSearchTitleViewHolderBinding viewBinding) {
|
||||
this(viewBinding.getRoot());
|
||||
this.viewBinding = viewBinding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindData(SearchTitleBean data, int position) {
|
||||
if (TextUtils.isEmpty(data.title)) {
|
||||
viewBinding.tvTitle.setText(data.titleRes);
|
||||
} else {
|
||||
viewBinding.tvTitle.setText(data.title);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.selector;
|
||||
|
||||
import static com.netease.nim.highavailable.HighAvailableObject.getContext;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.netease.nimlib.sdk.NIMClient;
|
||||
import com.netease.nimlib.sdk.RequestCallbackWrapper;
|
||||
import com.netease.nimlib.sdk.msg.MsgService;
|
||||
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
|
||||
import com.netease.nimlib.sdk.msg.model.RecentContact;
|
||||
import com.netease.yunxin.kit.chatkit.model.ConversationInfo;
|
||||
import com.netease.yunxin.kit.common.ui.activities.BaseActivity;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.LoadStatus;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.contact.ContactViewModel;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.search.SearchViewModel;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.model.UserInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
//选择好友数据Activity
|
||||
public abstract class FunBaseSelectorDataActivity extends BaseActivity {
|
||||
|
||||
|
||||
protected List<UserInfo> listmemebers = new ArrayList<>();
|
||||
protected ContactViewModel viewModel;
|
||||
protected SearchViewModel searchViewModel;
|
||||
private List<ContactFriendBean> accountList;
|
||||
private List<ContactFriendBean> lastlist;
|
||||
|
||||
public FunContactSelectorDialog contactSelectorDialog;
|
||||
|
||||
|
||||
//获取好友列表,最近联系,搜索好友
|
||||
public void initData() {
|
||||
viewModel = new ViewModelProvider(this).get(ContactViewModel.class);
|
||||
searchViewModel = new ViewModelProvider(this).get(SearchViewModel.class);
|
||||
viewModel
|
||||
.getContactLiveData()
|
||||
.observe(
|
||||
this,
|
||||
contactBeansResult -> {
|
||||
if (contactBeansResult.getLoadStatus() == LoadStatus.Success) {
|
||||
//好友列表
|
||||
accountList = contactBeansResult.getData();
|
||||
|
||||
}
|
||||
});
|
||||
viewModel.fetchContactList();
|
||||
|
||||
List<RecentContact> recentContact = NIMClient.getService(MsgService.class).queryRecentContactsBlock();
|
||||
if (recentContact != null && recentContact.size() > 0) {
|
||||
lastlist = convertConvacationList(recentContact);
|
||||
}
|
||||
// conversationViewModel = new ViewModelProvider(this).get(ConversationViewModel.class);
|
||||
// conversationViewModel
|
||||
// .getQueryLiveData()
|
||||
// .observe(
|
||||
// this,
|
||||
// result -> {
|
||||
// if (result.getLoadStatus() == LoadStatus.Success) {
|
||||
// lastlist = convertConvacationList(result.getData());
|
||||
// }
|
||||
//
|
||||
// });
|
||||
// conversationViewModel.fetchConversation();
|
||||
|
||||
searchViewModel.getQueryLiveData().observe(this, result -> {
|
||||
if (result.getLoadStatus() == LoadStatus.Success) {
|
||||
if (result.getData() != null && result.getData().size() > 0) {
|
||||
if (contactSelectorDialog != null) {
|
||||
contactSelectorDialog.showSearchResult(result.getData());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
public abstract List<ContactFriendBean> getLovelist();
|
||||
|
||||
public List<ContactFriendBean> convertConvacationList(List<RecentContact> list) {
|
||||
List<ContactFriendBean> contactFriendBeans = new ArrayList<>();
|
||||
for (RecentContact recentContact : list) {
|
||||
if (recentContact.getSessionType() == SessionTypeEnum.P2P) {
|
||||
ConversationInfo conversationInfo = new ConversationInfo(recentContact);
|
||||
FriendInfo friendInfo = conversationInfo.getFriendInfo();
|
||||
if(friendInfo!=null){
|
||||
friendInfo.setUserInfo(conversationInfo.getUserInfo());
|
||||
ContactFriendBean item = new ContactFriendBean(friendInfo);
|
||||
contactFriendBeans.add(item);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
return contactFriendBeans;
|
||||
}
|
||||
|
||||
public FunContactSelectorDialog showAddFriendsDialog(List<String> selectorlistkey, FunContactSelectorDialog.onActionClickListener onActionClickListener) {
|
||||
contactSelectorDialog = new FunContactSelectorDialog(this)
|
||||
.setSelector(selectorlistkey)
|
||||
.setTeamShow(false)
|
||||
.setActionTitle(getResources().getString(R.string.invite_sure))
|
||||
.setAccountList(accountList)
|
||||
.setLastList(lastlist)
|
||||
.setLoveList(getLovelist())
|
||||
.setActionListener(onActionClickListener);
|
||||
contactSelectorDialog.show();
|
||||
return contactSelectorDialog;
|
||||
|
||||
}
|
||||
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (null != this.getCurrentFocus()) {
|
||||
/**
|
||||
* 点击空白位置 隐藏软键盘
|
||||
*/
|
||||
InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
|
||||
return mInputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.selector;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.viewbinding.ViewBinding;
|
||||
|
||||
import com.netease.yunxin.kit.common.ui.utils.AvatarColor;
|
||||
import com.netease.yunxin.kit.common.ui.utils.ToastUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunContactSelectorSettingActivityBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunFriendSelectedViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.selector.BaseSelectedListAdapter;
|
||||
import com.netease.yunxin.kit.contactkit.ui.utils.ColorUtils;
|
||||
import com.netease.yunxin.kit.corekit.im.IMKitClient;
|
||||
import com.netease.yunxin.kit.corekit.im.model.UserInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
// 成员列表
|
||||
public class FunContactMembersAdapter extends RecyclerView.Adapter<FunContactMembersAdapter.FunContactMembersViewHolder> {
|
||||
|
||||
protected List<UserInfo> members;
|
||||
private Context mContext;
|
||||
|
||||
public FunContactMembersAdapter(Context context) {
|
||||
members = new ArrayList<>();
|
||||
this.mContext = context;
|
||||
}
|
||||
|
||||
protected FunContactMembersAdapter.ItemClickListener itemClickListener;
|
||||
|
||||
public void setItemClickListener(FunContactMembersAdapter.ItemClickListener itemClickListener) {
|
||||
this.itemClickListener = itemClickListener;
|
||||
}
|
||||
|
||||
public void setData(List<UserInfo> list) {
|
||||
members.addAll(list);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public FunContactMembersViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
return new FunContactMembersViewHolder(FunFriendSelectedViewHolderBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull FunContactMembersViewHolder holder, int position) {
|
||||
UserInfo userInfo = members.get(position);
|
||||
if (position == 0) {
|
||||
holder.binding.avatarView.setData(R.drawable.ic_creategroup_add, mContext.getResources().getString(R.string.fun_addmembers_txt));
|
||||
holder.binding.icClean.setVisibility(View.GONE);
|
||||
holder.binding.tvName.setTextColor(mContext.getResources().getColor(R.color.color_6d94ff));
|
||||
holder.binding.tvName.setText(mContext.getResources().getString(R.string.fun_addmembers_txt));
|
||||
} else {
|
||||
holder.binding.tvName.setTextColor(mContext.getResources().getColor(R.color.title_color));
|
||||
String avaterUrl = userInfo.getAvatar();
|
||||
// if (TextUtils.isEmpty(avaterUrl)) {
|
||||
// holder.binding.avatarView.setData(R.mipmap.default_head_img, userInfo.getName(), 0);
|
||||
// } else {
|
||||
// holder.binding.avatarView.setData(userInfo.getAvatar(), userInfo.getName(), AvatarColor.avatarColor(userInfo.getAccount()));
|
||||
// }
|
||||
ColorUtils.loadAvator(avaterUrl, holder.binding.avatarView);
|
||||
holder.binding.icClean.setVisibility(userInfo.getAccount().equals(IMKitClient.account()) ? View.GONE : View.VISIBLE);
|
||||
holder.binding.tvName.setText(userInfo.getName());
|
||||
}
|
||||
holder.binding.getRoot().setOnClickListener(view -> {
|
||||
if (itemClickListener != null) {
|
||||
if (position == 0) {
|
||||
itemClickListener.onAddClick();
|
||||
}
|
||||
if (position > 1) {
|
||||
if (getItemCount() == 3) {
|
||||
Toast.makeText(view.getContext(), mContext.getResources().getString(R.string.fun_addmemberstoast_txt), Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
removeFriend(userInfo);
|
||||
itemClickListener.onItemClick(userInfo);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void removeFriend(UserInfo userInfo) {
|
||||
int pos = members.indexOf(userInfo);
|
||||
if (pos >= 0) {
|
||||
members.remove(userInfo);
|
||||
notifyItemRemoved(pos);
|
||||
}
|
||||
}
|
||||
|
||||
public void addFriends(int size, List<UserInfo> userInfos) {
|
||||
members.addAll(userInfos);
|
||||
notifyItemRangeInserted(size, userInfos.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return members.size();
|
||||
}
|
||||
|
||||
|
||||
public interface ItemClickListener {
|
||||
void onItemClick(UserInfo item);
|
||||
|
||||
void onAddClick();
|
||||
}
|
||||
|
||||
protected class FunContactMembersViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
FunFriendSelectedViewHolderBinding binding;
|
||||
|
||||
public FunContactMembersViewHolder(@NonNull ViewBinding binding) {
|
||||
super(binding.getRoot());
|
||||
this.binding = (FunFriendSelectedViewHolderBinding) binding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,504 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.selector;
|
||||
|
||||
import static com.netease.yunxin.kit.contactkit.ui.selector.BaseContactSelectorActivity.DEFAULT_MAX_SELECT_COUNT;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.InsetDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.netease.yunxin.kit.alog.ALog;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.BaseBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunContactSelectorDialogLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.contact.FunContactDefaultFactory;
|
||||
import com.netease.yunxin.kit.contactkit.ui.interfaces.ContactActions;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.IViewTypeConstant;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.SearchFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.selector.BaseSelectedListAdapter;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListView;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class FunContactSelectorDialog extends Dialog {
|
||||
private static final String TAG = "FunBottomConfirmDialog";
|
||||
|
||||
private FunContactSelectorDialogLayoutBinding binding;
|
||||
|
||||
protected RecyclerView rvSelected;
|
||||
protected BaseSelectedListAdapter<?> selectedListAdapter;
|
||||
|
||||
private List<String> accountSelector;
|
||||
protected ContactListView contactListView;
|
||||
protected ContactListView lastContactView;
|
||||
protected ContactListView loveContactView;
|
||||
protected ContactListView searchContactView;
|
||||
|
||||
protected List<ContactFriendBean> accountList; //好友列表
|
||||
protected List<ContactFriendBean> lastlist; //最近联系
|
||||
protected List<ContactFriendBean> lovelist; //特别关心
|
||||
|
||||
|
||||
protected onActionClickListener onActionClickListener;
|
||||
protected onTeamQrClickListener onTeamQrClickListener;
|
||||
protected onSelectorItemClickListener onSelectorItemClickListener;
|
||||
|
||||
private boolean isTeamShow = false;
|
||||
|
||||
private Drawable insertDrawable;
|
||||
|
||||
private String actionTitle;
|
||||
|
||||
|
||||
public FunContactSelectorDialog(@NonNull Activity activity) {
|
||||
super(activity, R.style.SelectorFriendsBottomDialogTheme);
|
||||
renderRootView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (insertDrawable == null) {
|
||||
binding.getRoot().setBackground(getContext().getResources().getDrawable(R.drawable.fun_insert_topdialog));
|
||||
} else {
|
||||
binding.getRoot().setBackground(insertDrawable);
|
||||
}
|
||||
Window window = getWindow();
|
||||
if (window != null) {
|
||||
window.setGravity(Gravity.TOP);
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||
WindowManager.LayoutParams wlp = window.getAttributes();
|
||||
wlp.width = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
wlp.height = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
window.setAttributes(wlp);
|
||||
}
|
||||
setContentView(binding.getRoot());
|
||||
initTitleView();
|
||||
contactListView = binding.contactListView;
|
||||
lastContactView = binding.contactLast;
|
||||
searchContactView = binding.contactSearchlistView;
|
||||
loveContactView = binding.contactListViewMylove;
|
||||
rvSelected = binding.rvSelected;
|
||||
|
||||
setViewHolderFactory(contactListView);
|
||||
setViewHolderFactory(lastContactView);
|
||||
setViewHolderFactory(searchContactView);
|
||||
setViewHolderFactory(loveContactView);
|
||||
|
||||
binding.tvContactmember.setText(String.format(getContext().getResources().getString(R.string.fun_contactselector_members), accountList.size()));
|
||||
if (lastlist.size() > 0) {
|
||||
binding.tvContactlast.setVisibility(View.VISIBLE);
|
||||
binding.tvContactlast.setText(String.format(getContext().getResources().getString(R.string.fun_contactselector_last), lastlist.size()));
|
||||
lastContactView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (lovelist.size() > 0) {
|
||||
binding.tvContactspecialgz.setVisibility(View.VISIBLE);
|
||||
binding.tvContactspecialgz.setText(String.format(getContext().getResources().getString(R.string.fun_contactselector_mylove), lovelist.size()));
|
||||
loveContactView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
setBooleanCanSelector(accountList, contactListView);
|
||||
setBooleanCanSelector(lastlist, lastContactView);
|
||||
setBooleanCanSelector(lovelist, loveContactView);
|
||||
isTeamShow = getTeamShow();
|
||||
if (isTeamShow) {
|
||||
binding.lineTop.setVisibility(View.GONE);
|
||||
binding.llyTeamsetting.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
|
||||
LinearLayoutManager layoutManager =
|
||||
new LinearLayoutManager(getContext(), RecyclerView.HORIZONTAL, false);
|
||||
rvSelected.setLayoutManager(layoutManager);
|
||||
selectedListAdapter = new FunSelectedListAdapter();
|
||||
selectedListAdapter.setItemClickListener(
|
||||
item -> {
|
||||
item.setSelected(false);
|
||||
item.setCannotSelected(false);
|
||||
contactListView.updateContactData(item);
|
||||
lastContactView.updateContactData(item);
|
||||
searchContactView.updateContactData(item);
|
||||
loveContactView.updateContactData(item);
|
||||
updateActionTitle();
|
||||
});
|
||||
rvSelected.setAdapter(selectedListAdapter);
|
||||
setOnActionListener();
|
||||
setSearchView();
|
||||
setCanceledOnTouchOutside(true);
|
||||
setCancelable(true);
|
||||
}
|
||||
|
||||
private void initTitleView() {
|
||||
if (!TextUtils.isEmpty(actionTitle)) {
|
||||
binding.title.setActionText(actionTitle);
|
||||
// actionTitle = getContext().getResources().getString(R.string.invite_sure);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void setSearchView() {
|
||||
binding.editSelectorFriends.setOnEditorActionListener((textView, actionId, keyEvent) ->
|
||||
{
|
||||
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
|
||||
String search = textView.getEditableText().toString();
|
||||
//搜索好友
|
||||
if (onActionClickListener != null) {
|
||||
onActionClickListener.search(search);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
binding.editSelectorFriends.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
if (TextUtils.isEmpty(binding.editSelectorFriends.getText().toString())) {
|
||||
binding.icCleanEdit.setVisibility(View.GONE);
|
||||
binding.layoutContactlist.setVisibility(View.VISIBLE);
|
||||
binding.layoutSearchlist.setVisibility(View.GONE);
|
||||
} else {
|
||||
binding.icCleanEdit.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
binding.icCleanEdit.setOnClickListener(view -> binding.editSelectorFriends.setText(""));
|
||||
}
|
||||
|
||||
|
||||
public void showSearchResult(List<BaseBean> result) {
|
||||
binding.layoutSearchlist.setVisibility(View.VISIBLE);
|
||||
binding.layoutContactlist.setVisibility(View.GONE);
|
||||
for (ContactFriendBean bean : selectedListAdapter.getSelectedFriends()) {
|
||||
accountSelector.add(bean.data.getAccount());
|
||||
}
|
||||
List<ContactFriendBean> listsearch = convertSearchList(result);
|
||||
setBooleanCanSelector(listsearch, searchContactView);
|
||||
}
|
||||
|
||||
public List<ContactFriendBean> convertSearchList(List<BaseBean> list) {
|
||||
List<ContactFriendBean> contactFriendBeans = new ArrayList<>();
|
||||
LinkedList<ContactFriendBean> selected = selectedListAdapter.getSelectedFriends();
|
||||
for (BaseBean bean : list) {
|
||||
if (bean instanceof SearchFriendBean) {
|
||||
SearchFriendBean searchFriendBean = (SearchFriendBean) bean;
|
||||
FriendInfo friendInfo = searchFriendBean.friendSearchInfo.getFriendInfo();
|
||||
ContactFriendBean item = new ContactFriendBean(friendInfo);
|
||||
if (selected.size() > 0 && selected.contains(item)) {
|
||||
contactFriendBeans.add(selected.get(selected.indexOf(item)));
|
||||
} else {
|
||||
contactFriendBeans.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
return contactFriendBeans;
|
||||
}
|
||||
|
||||
public void setViewHolderFactory(ContactListView contactView) {
|
||||
contactView
|
||||
.getDecoration()
|
||||
.setTitleAlignBottom(true)
|
||||
.setShowTagOff(false)
|
||||
.setIndexDecorationBg(getContext().getResources().getColor(R.color.title_transfer))
|
||||
.setColorTitleBottomLine(getContext().getResources().getColor(R.color.title_transfer));
|
||||
FunContactDefaultFactory funContactDefaultFactory = new FunContactDefaultFactory();
|
||||
funContactDefaultFactory.setCenter(true);
|
||||
contactView.setViewHolderFactory(funContactDefaultFactory);
|
||||
}
|
||||
|
||||
//选中listener
|
||||
public void setOnActionListener() {
|
||||
ContactActions actions = new ContactActions();
|
||||
actions.addSelectorListener(
|
||||
IViewTypeConstant.CONTACT_FRIEND,
|
||||
(selector, data) -> {
|
||||
if (selector) {
|
||||
if (selectedListAdapter.getItemCount() >= DEFAULT_MAX_SELECT_COUNT) {
|
||||
Toast.makeText(
|
||||
getContext(),
|
||||
getContext().getString(
|
||||
R.string.contact_selector_max_count, String.valueOf(DEFAULT_MAX_SELECT_COUNT)),
|
||||
Toast.LENGTH_LONG)
|
||||
.show();
|
||||
((ContactFriendBean) data).setSelected(false);
|
||||
contactListView.updateContactData(data);
|
||||
lastContactView.updateContactData(data);
|
||||
searchContactView.updateContactData(data);
|
||||
loveContactView.updateContactData(data);
|
||||
} else {
|
||||
((ContactFriendBean) data).setSelected(true);
|
||||
contactListView.updateContactData(data);
|
||||
lastContactView.updateContactData(data);
|
||||
searchContactView.updateContactData(data);
|
||||
loveContactView.updateContactData(data);
|
||||
selectedListAdapter.addFriend((ContactFriendBean) data);
|
||||
}
|
||||
} else {
|
||||
((ContactFriendBean) data).setSelected(false);
|
||||
selectedListAdapter.removeFriend((ContactFriendBean) data);
|
||||
contactListView.updateContactData(data);
|
||||
lastContactView.updateContactData(data);
|
||||
loveContactView.updateContactData(data);
|
||||
searchContactView.updateContactData(data);
|
||||
}
|
||||
updateActionTitle();
|
||||
if (onSelectorItemClickListener != null) {
|
||||
onSelectorItemClickListener.selector(((ContactFriendBean) data).data.getAccount());
|
||||
|
||||
}
|
||||
});
|
||||
contactListView.setContactAction(actions);
|
||||
lastContactView.setContactAction(actions);
|
||||
searchContactView.setContactAction(actions);
|
||||
loveContactView.setContactAction(actions);
|
||||
}
|
||||
|
||||
public void updateActionTitle() {
|
||||
if (!TextUtils.isEmpty(actionTitle)) {
|
||||
String value = actionTitle;
|
||||
if (selectedListAdapter.getItemCount() > 0) {
|
||||
value = actionTitle + "(" + selectedListAdapter.getItemCount() + ")";
|
||||
}
|
||||
binding.title.setActionText(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//设置是否能选择
|
||||
public void setBooleanCanSelector(List<ContactFriendBean> list, ContactListView contactListView) {
|
||||
if (list.size() > 0) {
|
||||
for (ContactFriendBean bean : list) {
|
||||
bean.setCannotSelected(false);
|
||||
bean.setSelected(false);
|
||||
if (accountSelector.contains(bean.data.getAccount())) {
|
||||
bean.setCannotSelected(true);
|
||||
}
|
||||
}
|
||||
contactListView.onFriendDataSourceChanged(list);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public FunContactSelectorDialog setSelector(List<String> selector) {
|
||||
if (selector == null) {
|
||||
accountSelector = new ArrayList<>();
|
||||
} else {
|
||||
this.accountSelector = selector;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean getTeamShow() {
|
||||
return isTeamShow;
|
||||
}
|
||||
|
||||
public FunContactSelectorDialog setTeamShow(boolean teamShow) {
|
||||
isTeamShow = teamShow;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactSelectorDialog setInsertDrawable(Drawable drawable) {
|
||||
this.insertDrawable = drawable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactSelectorDialog setActionTitle(String actionText) {
|
||||
this.actionTitle = actionText;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactSelectorDialog setAccountList(List<ContactFriendBean> paramList) {
|
||||
if (paramList == null) {
|
||||
accountList = new ArrayList<>();
|
||||
} else {
|
||||
this.accountList = paramList;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactSelectorDialog setLastList(List<ContactFriendBean> paramLastList) {
|
||||
if (paramLastList == null) {
|
||||
lastlist = new ArrayList<>();
|
||||
} else {
|
||||
this.lastlist = paramLastList;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactSelectorDialog setLoveList(List<ContactFriendBean> paramLastList) {
|
||||
if (paramLastList == null) {
|
||||
lovelist = new ArrayList<>();
|
||||
} else {
|
||||
this.lovelist = paramLastList;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public FunContactSelectorDialog setActionListener(onActionClickListener actionListener) {
|
||||
this.onActionClickListener = actionListener;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactSelectorDialog setTeamQrClickListener(onTeamQrClickListener teamQrClickListener) {
|
||||
this.onTeamQrClickListener = teamQrClickListener;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FunContactSelectorDialog setOnSelectorItemClickListener(onSelectorItemClickListener itemClickListener) {
|
||||
this.onSelectorItemClickListener = itemClickListener;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* render page
|
||||
*/
|
||||
private void renderRootView() {
|
||||
binding = FunContactSelectorDialogLayoutBinding.inflate(getLayoutInflater());
|
||||
binding.title.getBackImageView().setImageResource(R.drawable.ic_dialog_close);
|
||||
binding.title.setOnBackIconClickListener(
|
||||
v -> {
|
||||
if (onSelectorItemClickListener != null) {
|
||||
onSelectorItemClickListener.close();
|
||||
}
|
||||
dismiss();
|
||||
});
|
||||
binding.title.setTitle(R.string.select)
|
||||
.setActionTextColor(getContext().getResources().getColor(R.color.color_6877fe))
|
||||
.setActionListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
//邀请
|
||||
if (onActionClickListener != null) {
|
||||
int newselectedsize = selectedListAdapter.getSelectedFriends().size();
|
||||
if (newselectedsize == 0) {
|
||||
Toast.makeText(
|
||||
getContext(),
|
||||
getContext().getString(
|
||||
R.string.select_empty_tips),
|
||||
Toast.LENGTH_LONG)
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
if (newselectedsize + accountSelector.size() > DEFAULT_MAX_SELECT_COUNT) {
|
||||
Toast.makeText(
|
||||
getContext(),
|
||||
getContext().getString(
|
||||
R.string.contact_selector_max_count, String.valueOf(DEFAULT_MAX_SELECT_COUNT)),
|
||||
Toast.LENGTH_LONG)
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
onActionClickListener.invited(getSelectedAccount(), getSelectedName(), getSelectedAvatar());
|
||||
}
|
||||
}
|
||||
});
|
||||
binding.tvTeamqr.setOnClickListener(view -> {
|
||||
if (onTeamQrClickListener != null) {
|
||||
onTeamQrClickListener.showTeamQR();
|
||||
}
|
||||
});
|
||||
binding.tvTeamurl.setOnClickListener(view -> {
|
||||
if (onTeamQrClickListener != null) {
|
||||
onTeamQrClickListener.showTeamUrl();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
protected ArrayList<String> getSelectedAccount() {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
for (ContactFriendBean bean : selectedListAdapter.getSelectedFriends()) {
|
||||
result.add(bean.data.getAccount());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected ArrayList<String> getSelectedName() {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
for (ContactFriendBean bean : selectedListAdapter.getSelectedFriends()) {
|
||||
if (bean.data.getUserInfo() == null) {
|
||||
continue;
|
||||
}
|
||||
String name = bean.data.getUserInfo().getName();
|
||||
result.add(TextUtils.isEmpty(name) ? bean.data.getAccount() : name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected ArrayList<String> getSelectedAvatar() {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
for (ContactFriendBean bean : selectedListAdapter.getSelectedFriends()) {
|
||||
if (bean.data.getUserInfo() == null) {
|
||||
continue;
|
||||
}
|
||||
String avatar = bean.data.getUserInfo().getAvatar();
|
||||
result.add(TextUtils.isEmpty(avatar) ? "" : avatar);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void dismiss() {
|
||||
if (!isShowing()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
super.dismiss();
|
||||
} catch (Throwable throwable) {
|
||||
ALog.e(TAG, "dismiss FunBottomConfirmDialog", throwable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface onActionClickListener {
|
||||
|
||||
void invited(List<String> listaccount, List<String> listname, List<String> listavat);
|
||||
|
||||
void search(String text);
|
||||
}
|
||||
|
||||
public interface onTeamQrClickListener {
|
||||
void showTeamQR();
|
||||
|
||||
void showTeamUrl();
|
||||
}
|
||||
|
||||
|
||||
public interface onSelectorItemClickListener {
|
||||
void close();
|
||||
|
||||
void selector(String userId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.selector;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.netease.yunxin.kit.common.ui.utils.AvatarColor;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunFriendSelectedViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.selector.BaseSelectedListAdapter;
|
||||
import com.netease.yunxin.kit.contactkit.ui.utils.ColorUtils;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendInfo;
|
||||
|
||||
public class FunSelectedListAdapter
|
||||
extends BaseSelectedListAdapter<FunFriendSelectedViewHolderBinding> {
|
||||
|
||||
@Override
|
||||
protected FunFriendSelectedViewHolderBinding provideViewBinding(
|
||||
@NonNull ViewGroup parent, int viewType) {
|
||||
return FunFriendSelectedViewHolderBinding.inflate(
|
||||
LayoutInflater.from(parent.getContext()), parent, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleBindViewHolder(
|
||||
SelectedViewHolder<FunFriendSelectedViewHolderBinding> holder,
|
||||
ContactFriendBean bean,
|
||||
FriendInfo friendData) {
|
||||
String friendAvaterUrl = friendData.getAvatar();
|
||||
ColorUtils.loadAvator(friendAvaterUrl,holder.binding.avatarView);
|
||||
|
||||
holder.binding.tvName.setText(friendData.getName());
|
||||
holder.itemView.setOnClickListener(
|
||||
v -> {
|
||||
removeFriend(bean);
|
||||
if (itemClickListener != null) {
|
||||
itemClickListener.onItemClick(bean);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.team;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.util.TypedValue;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.BaseListActivityLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.view.FunContactViewHolderFactory;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.view.viewholder.FunTeamListViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.IViewTypeConstant;
|
||||
import com.netease.yunxin.kit.contactkit.ui.team.BaseTeamListActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.team.TeamListViewModel;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import com.netease.yunxin.kit.corekit.route.XKitRouter;
|
||||
|
||||
public class FunTeamListActivity extends BaseTeamListActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
changeStatusBarColor(R.color.color_white);
|
||||
}
|
||||
|
||||
protected void configTitle(BaseListActivityLayoutBinding binding) {
|
||||
super.configTitle(binding);
|
||||
binding.title.getTitleTextView().setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
|
||||
// binding.title.getTitleTextView().setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
|
||||
binding.title.setBackgroundResource(R.color.color_white);
|
||||
}
|
||||
|
||||
protected void configRoutePath(TeamListViewModel viewModel) {
|
||||
viewModel.configRoutePath(RouterConstant.PATH_FUN_CHAT_TEAM_PAGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configViewHolderFactory() {
|
||||
binding.contactListView.setViewHolderFactory(
|
||||
new FunContactViewHolderFactory() {
|
||||
@Override
|
||||
protected BaseContactViewHolder getCustomViewHolder(ViewGroup view, int viewType) {
|
||||
if (viewType == IViewTypeConstant.CONTACT_TEAM_LIST) {
|
||||
FunTeamListViewHolder viewHolder = new FunTeamListViewHolder(view);
|
||||
viewHolder.setItemClickListener(
|
||||
data -> {
|
||||
if (isSelector) {
|
||||
Intent result = new Intent();
|
||||
result.putExtra(RouterConstant.KEY_TEAM_ID, data.data.getId());
|
||||
setResult(RESULT_OK, result);
|
||||
finish();
|
||||
} else {
|
||||
XKitRouter.withKey(data.router)
|
||||
.withParam(RouterConstant.CHAT_KRY, data.data)
|
||||
.withContext(FunTeamListActivity.this)
|
||||
.navigate();
|
||||
}
|
||||
});
|
||||
return viewHolder;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.userinfo;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.netease.yunxin.kit.common.ui.widgets.BackTitleBar;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunCommentActivityLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.userinfo.BaseCommentActivity;
|
||||
|
||||
public class FunCommentActivity extends BaseCommentActivity {
|
||||
|
||||
@Override
|
||||
protected View initViewAndGetRootView(Bundle savedInstanceState) {
|
||||
FunCommentActivityLayoutBinding binding =
|
||||
FunCommentActivityLayoutBinding.inflate(getLayoutInflater());
|
||||
titleBar = binding.title;
|
||||
titleBar.setActionTextColor(getResources().getColor(R.color.color_58be6b));
|
||||
edtComment = binding.edtComment;
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
changeStatusBarColor(R.color.color_ededed);
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
protected void configTitle(BackTitleBar titleBar) {
|
||||
super.configTitle(titleBar);
|
||||
titleBar.getTitleTextView().setTextSize(17);
|
||||
titleBar.getTitleTextView().setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.userinfo;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.netease.yunxin.kit.alog.ALog;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunContactBottomConfirmDialogBinding;
|
||||
|
||||
public class FunContactBottomConfirmDialog extends Dialog {
|
||||
private static final String TAG = "FunBottomConfirmDialog";
|
||||
|
||||
private Runnable confirmRunnable;
|
||||
private FunContactBottomConfirmDialogBinding binding;
|
||||
|
||||
public FunContactBottomConfirmDialog(@NonNull Activity activity) {
|
||||
super(activity, R.style.SelectorFriendsBottomDialogTheme);
|
||||
renderRootView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Window window = getWindow();
|
||||
if (window != null) {
|
||||
WindowManager.LayoutParams wlp = window.getAttributes();
|
||||
wlp.gravity = Gravity.BOTTOM;
|
||||
wlp.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
|
||||
wlp.width = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
wlp.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
window.setAttributes(wlp);
|
||||
}
|
||||
setContentView(binding.getRoot());
|
||||
setCanceledOnTouchOutside(true);
|
||||
setCancelable(true);
|
||||
|
||||
setOnDismissListener(dialog -> confirmRunnable = null);
|
||||
}
|
||||
|
||||
/** render page */
|
||||
private void renderRootView() {
|
||||
binding = FunContactBottomConfirmDialogBinding.inflate(getLayoutInflater());
|
||||
binding.tvDelete.setOnClickListener(
|
||||
v -> {
|
||||
if (confirmRunnable != null) {
|
||||
confirmRunnable.run();
|
||||
}
|
||||
dismiss();
|
||||
});
|
||||
binding.tvCancel.setOnClickListener(v -> dismiss());
|
||||
}
|
||||
|
||||
public FunContactBottomConfirmDialog configTip(String tip) {
|
||||
binding.tvTip.setText(tip);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void show(Runnable confirmRunnable) {
|
||||
if (isShowing()) {
|
||||
return;
|
||||
}
|
||||
this.confirmRunnable = confirmRunnable;
|
||||
try {
|
||||
super.show();
|
||||
} catch (Throwable throwable) {
|
||||
ALog.e(TAG, "show FunBottomConfirmDialog", throwable);
|
||||
}
|
||||
}
|
||||
|
||||
public void dismiss() {
|
||||
if (!isShowing()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
super.dismiss();
|
||||
} catch (Throwable throwable) {
|
||||
ALog.e(TAG, "dismiss FunBottomConfirmDialog", throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.userinfo;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
import com.netease.yunxin.kit.common.utils.NetworkUtils;
|
||||
import com.netease.yunxin.kit.common.utils.SizeUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunUserInfoActivityLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.userinfo.BaseUserInfoActivity;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import com.netease.yunxin.kit.corekit.route.XKitRouter;
|
||||
|
||||
public class FunUserInfoActivity extends BaseUserInfoActivity {
|
||||
|
||||
@Override
|
||||
protected View initViewAndGetRootView(Bundle savedInstanceState) {
|
||||
FunUserInfoActivityLayoutBinding binding =
|
||||
FunUserInfoActivityLayoutBinding.inflate(getLayoutInflater());
|
||||
contactInfoView = binding.contactUser;
|
||||
contactInfoView.configSCBlackSwitch(
|
||||
R.drawable.fun_switch_track_selector, R.drawable.fun_switch_thumb_selector);
|
||||
contactInfoView.configAvatarCorner(SizeUtils.dp2px(4));
|
||||
contactInfoView.configChatBtnColor(getResources().getColor(R.color.color_525c8c));
|
||||
contactInfoView.configDivideLineColor(getResources().getColor(R.color.color_ededed));
|
||||
contactInfoView.configRootBgColor(getResources().getColor(R.color.color_ededed));
|
||||
contactInfoView.configSignatureMaxLines(2);
|
||||
titleBar = binding.title;
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends Activity> getCommentActivity() {
|
||||
return FunCommentActivity.class;
|
||||
}
|
||||
|
||||
protected void showDeleteConfirmDialog() {
|
||||
new FunContactBottomConfirmDialog(this)
|
||||
.configTip(
|
||||
String.format(getString(R.string.delete_contact_account), userInfoData.getName()))
|
||||
.show(
|
||||
() -> {
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
Toast.makeText(this, R.string.contact_network_error_tip, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
viewModel.deleteFriend(userInfoData.data.getAccount());
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
protected void goChat() {
|
||||
XKitRouter.withKey(RouterConstant.PATH_FUN_CHAT_P2P_PAGE)
|
||||
.withParam(RouterConstant.CHAT_ID_KRY, userInfoData.data.getAccount())
|
||||
.withContext(FunUserInfoActivity.this)
|
||||
.navigate();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.verify;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.TypedValue;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
|
||||
import com.netease.yunxin.kit.common.ui.activities.BaseActivity;
|
||||
import com.netease.yunxin.kit.common.ui.utils.AvatarColor;
|
||||
import com.netease.yunxin.kit.contactkit.ui.ILoadListener;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.BaseListActivityLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunVerifyDetailsActivityBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.view.FunContactViewHolderFactory;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.view.viewholder.FunVerifyInfoViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactVerifyInfoBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.IViewTypeConstant;
|
||||
import com.netease.yunxin.kit.contactkit.ui.utils.ColorUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.verify.BaseVerifyListActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.verify.VerifyViewModel;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendNotify;
|
||||
import com.netease.yunxin.kit.corekit.im.model.SystemMessageInfoStatus;
|
||||
import com.netease.yunxin.kit.corekit.im.model.SystemMessageInfoType;
|
||||
import com.netease.yunxin.kit.corekit.im.model.UserInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FetchCallback;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import com.netease.yunxin.kit.corekit.route.XKitRouter;
|
||||
|
||||
/**
|
||||
* 好友申请详情信息
|
||||
*/
|
||||
public class FunVerifyDetailsActivity extends BaseActivity {
|
||||
|
||||
FunVerifyDetailsActivityBinding binding;
|
||||
protected VerifyViewModel viewModel;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
binding = FunVerifyDetailsActivityBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
viewModel = new ViewModelProvider(this).get(VerifyViewModel.class);
|
||||
configTitleBar();
|
||||
ContactVerifyInfoBean bean = (ContactVerifyInfoBean) getIntent().getSerializableExtra("bean");
|
||||
|
||||
if (bean != null) {
|
||||
UserInfo info = bean.data.getFromUserInfo();
|
||||
assert info != null;
|
||||
ColorUtils.loadAvator(info.getAvatar(),binding.avatarView);
|
||||
binding.tvName.setText(info.getName());
|
||||
FriendNotify notifyAttach = (FriendNotify) bean.data.getAttachObject();
|
||||
assert notifyAttach != null;
|
||||
binding.tvVerifymsg.setText(notifyAttach.getMsg());
|
||||
}
|
||||
|
||||
binding.tvAgree.setOnClickListener(view -> {
|
||||
viewModel.agree(
|
||||
bean,
|
||||
new FetchCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable Void param) {
|
||||
setResultBack(0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
setResultBack(-1, code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
setResultBack(-2, 0);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void setResultBack(int resultStatus, int errorCode) {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra("resultStatus", resultStatus);
|
||||
intent.putExtra("errorCode", errorCode);
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
}
|
||||
|
||||
public void configTitleBar() {
|
||||
binding.titleBarView.setOnBackIconClickListener(view -> onBackPressed());
|
||||
binding.titleBarView.getTitleTextView().setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.view;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.netease.yunxin.kit.contactkit.ui.IContactFactory;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.view.viewholder.FunContactViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.fun.view.viewholder.FunEntranceViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.IViewTypeConstant;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
|
||||
/**
|
||||
* viewHolder factory
|
||||
*/
|
||||
public abstract class FunContactViewHolderFactory implements IContactFactory {
|
||||
|
||||
@Override
|
||||
public int getItemViewType(BaseContactBean data) {
|
||||
return data.viewType;
|
||||
}
|
||||
|
||||
public BaseContactViewHolder createViewHolder(ViewGroup view, int viewType) {
|
||||
if (viewType == IViewTypeConstant.CONTACT_FRIEND) {
|
||||
FunContactViewHolder funContactViewHolder = new FunContactViewHolder(view);
|
||||
funContactViewHolder.setCenter(isCenter);
|
||||
return funContactViewHolder;
|
||||
} else if (viewType == IViewTypeConstant.CONTACT_ACTION_ENTER) {
|
||||
return new FunEntranceViewHolder(view);
|
||||
} else if (viewType >= IViewTypeConstant.CUSTOM_START) {
|
||||
return getCustomViewHolder(view, viewType);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isCenter = false;
|
||||
|
||||
public void setCenter(boolean isCenterShow) {
|
||||
this.isCenter = isCenterShow;
|
||||
}
|
||||
|
||||
protected abstract BaseContactViewHolder getCustomViewHolder(ViewGroup view, int viewType);
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.view.viewholder;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.netease.nim.highavailable.LogUtils;
|
||||
import com.netease.yunxin.kit.common.utils.SizeUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunBlackListViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactBlackListBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.utils.ColorUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListViewAttrs;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
import com.netease.yunxin.kit.corekit.im.model.UserInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FunBlackListViewHolder extends BaseContactViewHolder {
|
||||
private final int cornerSize = SizeUtils.dp2px(4);
|
||||
|
||||
private RelieveListener relieveListener;
|
||||
private ItemCheckedListener checkedListener;
|
||||
|
||||
private FunBlackListViewHolderBinding binding;
|
||||
|
||||
|
||||
public FunBlackListViewHolder(@NonNull ViewGroup itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initViewBinding(LayoutInflater layoutInflater, ViewGroup container) {
|
||||
binding = FunBlackListViewHolderBinding.inflate(layoutInflater, container, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(BaseContactBean bean, int position, ContactListViewAttrs attrs) {
|
||||
ContactBlackListBean blackListBean = ((ContactBlackListBean) bean);
|
||||
UserInfo friendData = ((ContactBlackListBean) bean).data;
|
||||
binding.tvName.setText(blackListBean.getName());
|
||||
binding.rbSelector.setChecked(false);
|
||||
|
||||
|
||||
// binding.avatarView.setCornerRadius(cornerSize);
|
||||
ColorUtils.loadAvator(friendData.getAvatar(),binding.avatarView);
|
||||
// binding.avatarView.setData(
|
||||
// friendData.getAvatar(),
|
||||
// blackListBean.getAvatarName(),
|
||||
// ColorUtils.avatarColor(friendData.getAccount()));
|
||||
|
||||
binding.tvRelieve.setOnClickListener(
|
||||
v -> {
|
||||
if (relieveListener != null) {
|
||||
relieveListener.onUserRelieve((ContactBlackListBean) bean);
|
||||
}
|
||||
});
|
||||
binding.rootView.setOnClickListener(view -> {
|
||||
binding.rbSelector.setChecked(!binding.rbSelector.isChecked());
|
||||
if (checkedListener != null) {
|
||||
checkedListener.onChecked((ContactBlackListBean) bean, binding.rbSelector.isChecked());
|
||||
}
|
||||
});
|
||||
loadConfig(attrs);
|
||||
}
|
||||
|
||||
private void loadConfig(ContactListViewAttrs attrs) {
|
||||
if (attrs == null) {
|
||||
return;
|
||||
}
|
||||
if (attrs.getNameTextColor() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvName.setTextColor(attrs.getNameTextColor());
|
||||
}
|
||||
if (attrs.getNameTextSize() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvName.setTextSize(attrs.getNameTextSize());
|
||||
}
|
||||
|
||||
if (attrs.getAvatarCornerRadius() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.avatarView.setCornerRadius(attrs.getAvatarCornerRadius());
|
||||
}
|
||||
}
|
||||
|
||||
public void setRelieveListener(RelieveListener relieveListener) {
|
||||
this.relieveListener = relieveListener;
|
||||
}
|
||||
|
||||
public void setItemCheckedListener(ItemCheckedListener checkedListener) {
|
||||
this.checkedListener = checkedListener;
|
||||
}
|
||||
|
||||
public interface RelieveListener {
|
||||
void onUserRelieve(ContactBlackListBean data);
|
||||
}
|
||||
|
||||
public interface ItemCheckedListener {
|
||||
void onChecked(ContactBlackListBean data, boolean isCheck);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.view.viewholder;
|
||||
|
||||
import static android.provider.Settings.System.getString;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.netease.nim.highavailable.LogUtils;
|
||||
import com.netease.nimlib.sdk.NIMClient;
|
||||
import com.netease.nimlib.sdk.msg.MsgService;
|
||||
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
|
||||
import com.netease.nimlib.sdk.msg.model.RecentContact;
|
||||
import com.netease.yunxin.kit.common.utils.SizeUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunFriendContactViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.utils.ColorUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.utils.GsonUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListViewAttrs;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendInfo;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class FunContactViewHolder extends BaseContactViewHolder {
|
||||
|
||||
FunFriendContactViewHolderBinding binding;
|
||||
private final int cornerSize = SizeUtils.dp2px(4);
|
||||
|
||||
public FunContactViewHolder(@NonNull ViewGroup itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initViewBinding(LayoutInflater layoutInflater, ViewGroup container) {
|
||||
binding = FunFriendContactViewHolderBinding.inflate(layoutInflater, container, true);
|
||||
}
|
||||
|
||||
private boolean isCenter = false;
|
||||
|
||||
|
||||
public void setCenter(boolean center) {
|
||||
isCenter = center;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(BaseContactBean bean, int position, ContactListViewAttrs attrs) {
|
||||
FriendInfo friendInfo = ((ContactFriendBean) bean).data;
|
||||
LogUtils.i("结构是啥:", "结构是啥:" + GsonUtils.beanToJSONString(bean));
|
||||
LogUtils.i("结构是啥:", "结构是啥1:" + GsonUtils.beanToJSONString(attrs));
|
||||
|
||||
if (friendInfo != null) {
|
||||
String nickName = friendInfo.getName();
|
||||
String avatarName = friendInfo.getAvatarName();
|
||||
String conversationText = ((ContactFriendBean) bean).getConversationText();
|
||||
binding.tvName.setText(nickName);
|
||||
binding.messageLayout.setVisibility(View.VISIBLE);
|
||||
binding.tvTime.setVisibility(View.VISIBLE);
|
||||
binding.tvTime.setText(((ContactFriendBean) bean).getConversationTime());
|
||||
if (isCenter) {
|
||||
binding.messageLayout.setVisibility(View.GONE);
|
||||
binding.tvTime.setVisibility(View.GONE);
|
||||
binding.unreadTv.setVisibility(View.GONE);
|
||||
}
|
||||
binding.tvHint.setText(binding.tvHint.getContext().getResources().getString(R.string.nmhmylg_txt));
|
||||
if (!TextUtils.isEmpty(conversationText)) {
|
||||
binding.tvHint.setText(conversationText);
|
||||
if (friendInfo.getUserInfo() != null) {
|
||||
binding.tvName.setText(friendInfo.getUserInfo().getName());
|
||||
}
|
||||
}
|
||||
String avaterUrl = friendInfo.getAvatar();
|
||||
if (TextUtils.isEmpty(avaterUrl)) {
|
||||
binding.avatarView.setData(R.mipmap.default_head_img
|
||||
, avatarName, 0);
|
||||
} else {
|
||||
binding.avatarView.setData(
|
||||
friendInfo.getAvatar(), avatarName, ColorUtils.avatarColor(friendInfo.getAccount()));
|
||||
}
|
||||
|
||||
if (attrs.getShowSelector()) {
|
||||
binding.layoutSelector.setVisibility(View.VISIBLE);
|
||||
if (((ContactFriendBean) bean).isCannotSelected()) {
|
||||
binding.rbSelector.setVisibility(View.GONE);
|
||||
binding.ivSelector.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
binding.ivSelector.setVisibility(View.GONE);
|
||||
binding.rbSelector.setChecked(((ContactFriendBean) bean).isSelected());
|
||||
binding.rbSelector.setVisibility(View.VISIBLE);
|
||||
binding.rootView.setOnClickListener(
|
||||
v -> {
|
||||
boolean newStatue = !binding.rbSelector.isChecked();
|
||||
((ContactFriendBean) bean).setSelected(newStatue);
|
||||
binding.rbSelector.setChecked(newStatue);
|
||||
if (actions != null && actions.getSelectorListener(bean.viewType) != null) {
|
||||
actions.getSelectorListener(bean.viewType).onSelector(newStatue, bean);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
binding.rbSelector.setVisibility(View.GONE);
|
||||
binding.rootView.setOnClickListener(
|
||||
v -> {
|
||||
if (actions != null && actions.getContactListener(bean.viewType) != null) {
|
||||
actions.getContactListener(bean.viewType).onClick(position, bean);
|
||||
}
|
||||
});
|
||||
}
|
||||
RecentContact recentContact = NIMClient.getService(MsgService.class).queryRecentContact(friendInfo.getAccount(), SessionTypeEnum.P2P);
|
||||
if (recentContact != null) {
|
||||
// if (recentContact.getUnreadCount() > 0) {
|
||||
// int count = recentContact.getUnreadCount();
|
||||
// String content;
|
||||
// if (count >= 100) {
|
||||
// content = "99+";
|
||||
// } else {
|
||||
// content = String.valueOf(count);
|
||||
// }
|
||||
// binding.unreadTv.setText(content);
|
||||
// binding.unreadTv.setVisibility(View.VISIBLE);
|
||||
// } else {
|
||||
// binding.unreadTv.setVisibility(View.GONE);
|
||||
// }
|
||||
binding.tvHint.setText(recentContact.getContent());
|
||||
if (recentContact.getContent().equals("[自定义消息]")) {
|
||||
String bean2 = GsonUtils.beanToJSONString(recentContact.getAttachment());
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(bean2);
|
||||
switch ((int) jsonObject.get("type")) {
|
||||
case 1002:
|
||||
binding.tvHint.setText(binding.unreadTv.getResources().getString(R.string.voom_message_txt));
|
||||
break;
|
||||
case 1003:
|
||||
binding.tvHint.setText(binding.unreadTv.getResources().getString(R.string.gerenminp_txt));
|
||||
break;
|
||||
case 1004:
|
||||
binding.tvHint.setText(binding.unreadTv.getResources().getString(R.string.zhuanzhang_chat_txt));
|
||||
break;
|
||||
case 1005:
|
||||
case 1006:
|
||||
binding.tvHint.setText(binding.unreadTv.getResources().getString(R.string.hongbao_chat_txt));
|
||||
break;
|
||||
case 1007:
|
||||
binding.tvHint.setText(binding.unreadTv.getResources().getString(R.string.albums_chat_txt));
|
||||
break;
|
||||
case 1008:
|
||||
binding.tvHint.setText(binding.unreadTv.getResources().getString(R.string.helppay_chat_txt));
|
||||
break;
|
||||
case 1009:
|
||||
binding.tvHint.setText(binding.unreadTv.getResources().getString(R.string.inviteGroup_chat_txt));
|
||||
break;
|
||||
default:
|
||||
binding.tvHint.setText(binding.unreadTv.getResources().getString(R.string.custom_chat_txt));
|
||||
|
||||
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
binding.unreadTv.setVisibility(View.GONE);
|
||||
|
||||
}
|
||||
|
||||
// loadConfig(attrs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void loadConfig(ContactListViewAttrs attrs) {
|
||||
if (attrs == null) {
|
||||
return;
|
||||
}
|
||||
if (attrs.getNameTextColor() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvName.setTextColor(attrs.getNameTextColor());
|
||||
}
|
||||
if (attrs.getNameTextSize() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvName.setTextSize(attrs.getNameTextSize());
|
||||
}
|
||||
|
||||
if (attrs.getAvatarCornerRadius() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.avatarView.setCornerRadius(attrs.getAvatarCornerRadius());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.view.viewholder;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunEntranceContactViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactEntranceBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListViewAttrs;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
|
||||
public class FunEntranceViewHolder extends BaseContactViewHolder {
|
||||
|
||||
FunEntranceContactViewHolderBinding binding;
|
||||
private static final int maxNumber = 99;
|
||||
|
||||
public FunEntranceViewHolder(@NonNull ViewGroup itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initViewBinding(LayoutInflater layoutInflater, ViewGroup container) {
|
||||
binding = FunEntranceContactViewHolderBinding.inflate(layoutInflater, container, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(BaseContactBean bean, int position, ContactListViewAttrs attrs) {
|
||||
ContactEntranceBean entranceBean = (ContactEntranceBean) bean;
|
||||
if (entranceBean.showRightArrow) {
|
||||
binding.ivArrow.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
binding.ivArrow.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (entranceBean.number > 0) {
|
||||
binding.tvNumber.setVisibility(View.VISIBLE);
|
||||
String numberValue = String.valueOf(entranceBean.number);
|
||||
if (entranceBean.number > maxNumber) {
|
||||
numberValue = context.getResources().getString(R.string.verify_max_count_text);
|
||||
}
|
||||
binding.tvNumber.setText(numberValue);
|
||||
} else {
|
||||
binding.tvNumber.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
Glide.with(context).load(entranceBean.icon).centerCrop().into(binding.ivIcon);
|
||||
|
||||
binding.tvTitle.setText(entranceBean.title);
|
||||
|
||||
binding.rootView.setOnClickListener(
|
||||
v -> {
|
||||
if (actions != null && actions.getContactListener(bean.viewType) != null) {
|
||||
actions.getContactListener(bean.viewType).onClick(position, bean);
|
||||
}
|
||||
});
|
||||
|
||||
loadConfig(attrs);
|
||||
}
|
||||
|
||||
private void loadConfig(ContactListViewAttrs attrs) {
|
||||
if (attrs == null) {
|
||||
return;
|
||||
}
|
||||
if (attrs.getNameTextColor() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvTitle.setTextColor(attrs.getNameTextColor());
|
||||
}
|
||||
if (attrs.getNameTextSize() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvTitle.setTextSize(attrs.getNameTextSize());
|
||||
}
|
||||
|
||||
if (attrs.getAvatarCornerRadius() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.flIvIcon.setRadius(attrs.getAvatarCornerRadius());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.view.viewholder;
|
||||
|
||||
import static android.provider.Settings.System.getString;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.netease.nimlib.sdk.NIMClient;
|
||||
import com.netease.nimlib.sdk.msg.MsgService;
|
||||
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
|
||||
import com.netease.nimlib.sdk.msg.model.RecentContact;
|
||||
import com.netease.nimlib.sdk.team.model.Team;
|
||||
import com.netease.yunxin.kit.common.utils.SizeUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunTeamListViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactTeamBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.utils.ColorUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.utils.GsonUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListViewAttrs;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class FunTeamListViewHolder extends BaseContactViewHolder {
|
||||
// private final int cornerSize = SizeUtils.dp2px(4);
|
||||
|
||||
private itemClickListener itemClickListener;
|
||||
|
||||
private FunTeamListViewHolderBinding binding;
|
||||
|
||||
public FunTeamListViewHolder(@NonNull ViewGroup itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initViewBinding(LayoutInflater layoutInflater, ViewGroup container) {
|
||||
binding = FunTeamListViewHolderBinding.inflate(layoutInflater, container, true);
|
||||
}
|
||||
|
||||
private boolean isCenter = false;
|
||||
|
||||
public void setCenter(boolean center) {
|
||||
isCenter = center;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(BaseContactBean bean, int position, ContactListViewAttrs attrs) {
|
||||
Team teamInfo = ((ContactTeamBean) bean).data;
|
||||
if (teamInfo != null) {
|
||||
binding.tvName.setText(teamInfo.getName());
|
||||
String value = ((ContactTeamBean) bean).getContent();
|
||||
String time = ((ContactTeamBean) bean).getTime();
|
||||
binding.tvHint.setText(TextUtils.isEmpty(value) ? binding.tvHint.getContext().getResources().getString(R.string.nmhmylg_txt) : value);
|
||||
binding.tvTime.setText(TextUtils.isEmpty(time) ? "" : time);
|
||||
// binding.avatarView.setCornerRadius(cornerSize);
|
||||
binding.messageLayout.setVisibility(View.VISIBLE);
|
||||
binding.tvTime.setVisibility(View.VISIBLE);
|
||||
if (isCenter) {
|
||||
binding.messageLayout.setVisibility(View.GONE);
|
||||
binding.tvTime.setVisibility(View.GONE);
|
||||
}
|
||||
ColorUtils.loadGroupAvator(teamInfo.getIcon(),binding.avatarView);
|
||||
binding.rootView.setOnClickListener(
|
||||
v -> {
|
||||
if (itemClickListener != null) {
|
||||
itemClickListener.onClick((ContactTeamBean) bean);
|
||||
}
|
||||
});
|
||||
|
||||
RecentContact recentContact = NIMClient.getService(MsgService.class).queryRecentContact(teamInfo.getId(), SessionTypeEnum.Team);
|
||||
if (recentContact != null) {
|
||||
// if (recentContact.getUnreadCount() > 0) {
|
||||
// int count = recentContact.getUnreadCount();
|
||||
// String content;
|
||||
// if (count >= 100) {
|
||||
// content = "99+";
|
||||
// } else {
|
||||
// content = String.valueOf(count);
|
||||
// }
|
||||
// binding.unreadTv.setText(content);
|
||||
// binding.unreadTv.setVisibility(View.VISIBLE);
|
||||
// } else {
|
||||
// binding.unreadTv.setVisibility(View.GONE);
|
||||
// }
|
||||
|
||||
binding.tvHint.setText(recentContact.getContent());
|
||||
if (recentContact.getContent().equals("[自定义消息]")) {
|
||||
String bean2 = GsonUtils.beanToJSONString(recentContact.getAttachment());
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(bean2);
|
||||
switch ((int) jsonObject.get("type")) {
|
||||
case 1002:
|
||||
binding.tvHint.setText(binding.unreadTv.getResources().getString(R.string.voom_message_txt));
|
||||
break;
|
||||
case 1003:
|
||||
binding.tvHint.setText(binding.unreadTv.getResources().getString(R.string.gerenminp_txt));
|
||||
break;
|
||||
case 1004:
|
||||
binding.tvHint.setText(binding.unreadTv.getResources().getString(R.string.zhuanzhang_chat_txt));
|
||||
break;
|
||||
case 1005:
|
||||
case 1006:
|
||||
binding.tvHint.setText(binding.unreadTv.getResources().getString(R.string.hongbao_chat_txt));
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}else{
|
||||
binding.unreadTv.setVisibility(View.GONE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
loadConfig(attrs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void loadConfig(ContactListViewAttrs attrs) {
|
||||
if (attrs == null) {
|
||||
return;
|
||||
}
|
||||
if (attrs.getNameTextColor() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvName.setTextColor(attrs.getNameTextColor());
|
||||
}
|
||||
if (attrs.getNameTextSize() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvName.setTextSize(attrs.getNameTextSize());
|
||||
}
|
||||
|
||||
if (attrs.getAvatarCornerRadius() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.avatarView.setCornerRadius(attrs.getAvatarCornerRadius());
|
||||
}
|
||||
}
|
||||
|
||||
public void setItemClickListener(FunTeamListViewHolder.itemClickListener itemClickListener) {
|
||||
this.itemClickListener = itemClickListener;
|
||||
}
|
||||
|
||||
public interface itemClickListener {
|
||||
void onClick(ContactTeamBean data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.fun.view.viewholder;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.netease.nim.highavailable.LogUtils;
|
||||
import com.netease.nimlib.sdk.friend.model.AddFriendNotify;
|
||||
import com.netease.yunxin.kit.chatkit.repo.ContactRepo;
|
||||
import com.netease.yunxin.kit.common.ui.utils.AvatarColor;
|
||||
import com.netease.yunxin.kit.common.utils.SizeUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FunVerifyListViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactVerifyInfoBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.utils.ColorUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListViewAttrs;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendNotify;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendVerifyType;
|
||||
import com.netease.yunxin.kit.corekit.im.model.SystemMessageInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.model.SystemMessageInfoStatus;
|
||||
import com.netease.yunxin.kit.corekit.im.model.SystemMessageInfoType;
|
||||
|
||||
public class FunVerifyInfoViewHolder extends BaseContactViewHolder {
|
||||
private final int cornerSize = SizeUtils.dp2px(4);
|
||||
|
||||
private VerifyListener verifyListener;
|
||||
|
||||
private FunVerifyListViewHolderBinding binding;
|
||||
|
||||
public FunVerifyInfoViewHolder(@NonNull ViewGroup itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initViewBinding(LayoutInflater layoutInflater, ViewGroup container) {
|
||||
binding = FunVerifyListViewHolderBinding.inflate(layoutInflater, container, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(BaseContactBean bean, int position, ContactListViewAttrs attrs) {
|
||||
ContactVerifyInfoBean infoBean = ((ContactVerifyInfoBean) bean);
|
||||
SystemMessageInfo info = infoBean.data;
|
||||
String name = info.getFromUserName();
|
||||
String targetName = info.getTargetName();
|
||||
// String avatar =
|
||||
// info.getTargetTeam() != null
|
||||
// ? info.getTargetTeam().getIcon()
|
||||
// : info.getFromUserInfo().getAvatar();
|
||||
if(!TextUtils.isEmpty(info.getFromAccount())){
|
||||
FriendInfo friendInfo = ContactRepo.getFriend(info.getFromAccount());
|
||||
if (friendInfo != null && !TextUtils.isEmpty(friendInfo.getAlias())) {
|
||||
name = friendInfo.getAlias();
|
||||
}
|
||||
}
|
||||
|
||||
binding.tvName.setText(name);
|
||||
// binding.avatarView.setCornerRadius(cornerSize);
|
||||
if (info.getTargetTeam() == null) {
|
||||
ColorUtils.loadAvator(info.getFromUserInfo().getAvatar(), binding.avatarView);
|
||||
} else {
|
||||
ColorUtils.loadGroupAvator(info.getTargetTeam().getIcon(), binding.avatarView);
|
||||
}
|
||||
|
||||
// binding.avatarView.setData(avatar, name, AvatarColor.avatarColor(info.getFromAccount()));
|
||||
int unreadCount = infoBean.getUnreadCount();
|
||||
if (unreadCount > 1) {
|
||||
binding.unreadTv.setVisibility(View.VISIBLE);
|
||||
if (unreadCount > 99) {
|
||||
binding.unreadTv.setText(context.getString(R.string.verify_max_count_text));
|
||||
} else {
|
||||
binding.unreadTv.setText(String.valueOf(unreadCount));
|
||||
}
|
||||
} else {
|
||||
binding.unreadTv.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (infoBean.data.getUnread()) {
|
||||
binding.rootView.setBackgroundColor(context.getResources().getColor(R.color.color_ededef));
|
||||
} else {
|
||||
binding.rootView.setBackgroundColor(context.getResources().getColor(R.color.color_white));
|
||||
}
|
||||
|
||||
switch (info.getInfoStatus()) {
|
||||
case Init:
|
||||
binding.llyVerifyResult.setVisibility(View.GONE);
|
||||
binding.llyVerify.setVisibility(View.VISIBLE);
|
||||
binding.tvAccept.setOnClickListener(
|
||||
v -> {
|
||||
if (verifyListener != null) {
|
||||
verifyListener.onAccept((ContactVerifyInfoBean) bean);
|
||||
binding.tvAccept.setEnabled(false);
|
||||
}
|
||||
});
|
||||
binding.tvReject.setOnClickListener(
|
||||
v -> {
|
||||
if (verifyListener != null) {
|
||||
verifyListener.onReject((ContactVerifyInfoBean) bean);
|
||||
binding.tvReject.setEnabled(false);
|
||||
}
|
||||
});
|
||||
binding.rootView.setOnClickListener(view -> {
|
||||
if (verifyListener != null) {
|
||||
if (info.getAttachObject() instanceof FriendNotify) {
|
||||
FriendNotify notifyAttach = (FriendNotify) info.getAttachObject();
|
||||
if (notifyAttach.getType() == FriendVerifyType.VerifyRequest && info.getInfoStatus() == SystemMessageInfoStatus.Init) {
|
||||
verifyListener.onDetails((ContactVerifyInfoBean) bean);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
case Passed:
|
||||
showResult(context.getString(R.string.contact_verify_agreed), true);
|
||||
break;
|
||||
case Declined:
|
||||
showResult(context.getString(R.string.contact_verify_rejected), false);
|
||||
break;
|
||||
case Ignored:
|
||||
case Expired:
|
||||
showResult(context.getString(R.string.contact_verify_expired), false);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (info.getInfoType()) {
|
||||
case ApplyJoinTeam:
|
||||
binding.tvAction.setText(
|
||||
String.format(context.getString(R.string.apply_to_join_group), targetName));
|
||||
break;
|
||||
case RejectTeamApply:
|
||||
binding.tvAction.setText(
|
||||
String.format(context.getString(R.string.apply_to_join_group), targetName));
|
||||
showResult(context.getString(R.string.contact_verify_agreed), false);
|
||||
break;
|
||||
case TeamInvite:
|
||||
binding.tvAction.setText(
|
||||
String.format(context.getString(R.string.invited_to_join_group), targetName));
|
||||
break;
|
||||
case DeclineTeamInvite:
|
||||
binding.tvAction.setText(
|
||||
String.format(context.getString(R.string.invited_to_join_group), targetName));
|
||||
showResult(context.getString(R.string.contact_verify_agreed), false);
|
||||
break;
|
||||
case AddFriend:
|
||||
if (info.getAttachObject() != null && info.getAttachObject() instanceof FriendNotify) {
|
||||
FriendNotify notifyAttach = (FriendNotify) info.getAttachObject();
|
||||
if (notifyAttach.getType() == FriendVerifyType.AgreeAdd) {
|
||||
binding.tvAction.setText(R.string.accept_your_friend_apply);
|
||||
showResult(null, true);
|
||||
} else if (notifyAttach.getType() == FriendVerifyType.DirectAdd) {
|
||||
binding.tvAction.setText(R.string.direct_add_your_friend_apply);
|
||||
showResult(null, true);
|
||||
} else if (notifyAttach.getType() == FriendVerifyType.RejectAdd) {
|
||||
binding.tvAction.setText(R.string.reject_your_friend_apply);
|
||||
showResult(null, true);
|
||||
} else if (notifyAttach.getType() == FriendVerifyType.VerifyRequest) {
|
||||
binding.tvAction.setText(R.string.friend_apply);
|
||||
}
|
||||
} else {
|
||||
binding.tvAction.setText(R.string.friend_apply);
|
||||
}
|
||||
break;
|
||||
case Undefined:
|
||||
break;
|
||||
}
|
||||
|
||||
loadConfig(attrs);
|
||||
}
|
||||
|
||||
private void loadConfig(ContactListViewAttrs attrs) {
|
||||
if (attrs == null) {
|
||||
return;
|
||||
}
|
||||
if (attrs.getNameTextColor() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvName.setTextColor(attrs.getNameTextColor());
|
||||
}
|
||||
if (attrs.getNameTextSize() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvName.setTextSize(attrs.getNameTextSize());
|
||||
}
|
||||
|
||||
if (attrs.getAvatarCornerRadius() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.avatarView.setCornerRadius(attrs.getAvatarCornerRadius());
|
||||
}
|
||||
}
|
||||
|
||||
private void showResult(String content, boolean agreeIcon) {
|
||||
if (!TextUtils.isEmpty(content)) {
|
||||
binding.tvVerifyResult.setText(content);
|
||||
binding.ivVerifyResult.setImageResource(
|
||||
agreeIcon ? R.mipmap.ic_agree_status : R.mipmap.ic_reject_status);
|
||||
binding.llyVerifyResult.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
binding.llyVerifyResult.setVisibility(View.GONE);
|
||||
}
|
||||
binding.llyVerify.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
public void setVerifyListener(VerifyListener verifyListener) {
|
||||
this.verifyListener = verifyListener;
|
||||
}
|
||||
|
||||
public interface VerifyListener {
|
||||
void onAccept(ContactVerifyInfoBean bean);
|
||||
|
||||
void onReject(ContactVerifyInfoBean bean);
|
||||
|
||||
void onDetails(ContactVerifyInfoBean bean);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,394 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.indexbar;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.indexbar.bean.IndexPinyinBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.indexbar.helper.IIndexBarDataHelper;
|
||||
import com.netease.yunxin.kit.contactkit.ui.indexbar.helper.IndexBarDataHelperImpl;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/** index bar in the right of contact */
|
||||
public class IndexBar extends View {
|
||||
|
||||
public IndexBar(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public IndexBar(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public IndexBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public static String[] INDEX_STRING = {
|
||||
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
|
||||
"T", "U", "V", "W", "X", "Y", "Z", "#"
|
||||
};
|
||||
|
||||
// whether need get index from data(if only A,B,C,show A B C Tag only)
|
||||
private boolean isNeedRealIndex;
|
||||
|
||||
private List<String> mIndexDataList;
|
||||
|
||||
//width and height for view
|
||||
private int mWidth, mHeight;
|
||||
|
||||
//height for item
|
||||
private int mGapHeight;
|
||||
|
||||
//pressed index
|
||||
int pressI = -1;
|
||||
|
||||
private Paint mPaint;
|
||||
|
||||
//paint for background
|
||||
private Paint backgroundPaint;
|
||||
|
||||
private int mPressedBackground;
|
||||
|
||||
@ColorInt private int textColor;
|
||||
|
||||
@ColorInt private int textColorPressed;
|
||||
|
||||
private IIndexBarDataHelper mDataHelper;
|
||||
|
||||
//this TextView will be set outside,it will show selected tag
|
||||
private TextView mPressedShowTextView;
|
||||
private boolean isSourceDataAlreadySorted;
|
||||
private List<? extends IndexPinyinBean> mSourceData;
|
||||
private LinearLayoutManager mLayoutManager;
|
||||
private int mHeaderViewCount = 0;
|
||||
private onIndexPressedListener mOnIndexPressedListener;
|
||||
|
||||
public int getHeaderViewCount() {
|
||||
return mHeaderViewCount;
|
||||
}
|
||||
|
||||
public IndexBar setHeaderViewCount(int headerViewCount) {
|
||||
mHeaderViewCount = headerViewCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isSourceDataAlreadySorted() {
|
||||
return isSourceDataAlreadySorted;
|
||||
}
|
||||
|
||||
public IndexBar setSourceDataAlreadySorted(boolean sourceDataAlreadySorted) {
|
||||
isSourceDataAlreadySorted = sourceDataAlreadySorted;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IIndexBarDataHelper getDataHelper() {
|
||||
return mDataHelper;
|
||||
}
|
||||
|
||||
public IndexBar setDataHelper(IIndexBarDataHelper dataHelper) {
|
||||
mDataHelper = dataHelper;
|
||||
return this;
|
||||
}
|
||||
|
||||
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
int textSize =
|
||||
(int)
|
||||
TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_SP,
|
||||
8,
|
||||
getResources().getDisplayMetrics()); //default text size
|
||||
textColor = getContext().getResources().getColor(R.color.color_14131b);
|
||||
textColorPressed = getContext().getResources().getColor(R.color.color_ffffff);
|
||||
mPressedBackground = Color.TRANSPARENT; //default background color
|
||||
TypedArray typedArray =
|
||||
context.getTheme().obtainStyledAttributes(attrs, R.styleable.IndexBar, defStyleAttr, 0);
|
||||
int n = typedArray.getIndexCount();
|
||||
for (int i = 0; i < n; i++) {
|
||||
int attr = typedArray.getIndex(i);
|
||||
if (attr == R.styleable.IndexBar_indexBarTextSize) {
|
||||
textSize = typedArray.getDimensionPixelSize(attr, textSize);
|
||||
} else if (attr == R.styleable.IndexBar_indexBarPressBackground) {
|
||||
mPressedBackground = typedArray.getColor(attr, mPressedBackground);
|
||||
} else if (attr == R.styleable.IndexBar_indexBarTextColor) {
|
||||
textColor = typedArray.getColor(attr, textColor);
|
||||
} else if (attr == R.styleable.IndexBar_indexBarTextColorPress) {
|
||||
textColorPressed = typedArray.getColor(attr, textColorPressed);
|
||||
}
|
||||
}
|
||||
typedArray.recycle();
|
||||
|
||||
initIndexData();
|
||||
|
||||
mPaint = new Paint();
|
||||
mPaint.setAntiAlias(true);
|
||||
mPaint.setTextSize(textSize);
|
||||
mPaint.setColor(textColor);
|
||||
|
||||
backgroundPaint = new Paint();
|
||||
backgroundPaint.setAntiAlias(true);
|
||||
backgroundPaint.setColor(context.getResources().getColor(R.color.color_537ff4));
|
||||
|
||||
//set default index pressed listener
|
||||
setOnIndexPressedListener(
|
||||
new onIndexPressedListener() {
|
||||
@Override
|
||||
public void onIndexPressed(int index, String text) {
|
||||
//show hintTextView
|
||||
if (mPressedShowTextView != null) {
|
||||
mPressedShowTextView.setVisibility(View.VISIBLE);
|
||||
mPressedShowTextView.setText(text);
|
||||
}
|
||||
//scroll recycleView
|
||||
if (mLayoutManager != null) {
|
||||
int position = getPosByTag(text);
|
||||
if (position != -1) {
|
||||
mLayoutManager.scrollToPositionWithOffset(position, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMotionEventEnd() {
|
||||
//hide hintTextView
|
||||
if (mPressedShowTextView != null) {
|
||||
mPressedShowTextView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mDataHelper = new IndexBarDataHelperImpl();
|
||||
}
|
||||
|
||||
public void configIndexTextBGColor(int color) {
|
||||
backgroundPaint.setColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
//get Mode and Size
|
||||
int wMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||
int wSize = MeasureSpec.getSize(widthMeasureSpec);
|
||||
int hMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
int hSize = MeasureSpec.getSize(heightMeasureSpec);
|
||||
|
||||
int measureWidth = 0, measureHeight = 0;
|
||||
//rect for index
|
||||
Rect indexBounds = new Rect();
|
||||
String index; //index tag
|
||||
for (int i = 0; i < mIndexDataList.size(); i++) {
|
||||
index = mIndexDataList.get(i);
|
||||
mPaint.getTextBounds(
|
||||
index, 0, index.length(), indexBounds); //get width and height for text rect
|
||||
measureWidth = Math.max(indexBounds.width(), measureWidth); //get max width for index
|
||||
measureHeight = Math.max(indexBounds.height(), measureHeight); //get max height for index
|
||||
}
|
||||
measureHeight *= mIndexDataList.size(); //total index
|
||||
switch (wMode) {
|
||||
case MeasureSpec.EXACTLY:
|
||||
measureWidth = wSize;
|
||||
break;
|
||||
case MeasureSpec.AT_MOST:
|
||||
measureWidth = Math.min(measureWidth, wSize);
|
||||
break;
|
||||
case MeasureSpec.UNSPECIFIED:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (hMode) {
|
||||
case MeasureSpec.EXACTLY:
|
||||
measureHeight = hSize;
|
||||
break;
|
||||
case MeasureSpec.AT_MOST:
|
||||
measureHeight = Math.min(measureHeight, hSize);
|
||||
break;
|
||||
case MeasureSpec.UNSPECIFIED:
|
||||
break;
|
||||
}
|
||||
|
||||
setMeasuredDimension(measureWidth, measureHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
int t = getPaddingTop();
|
||||
String index; //index to draw
|
||||
for (int i = 0; i < mIndexDataList.size(); i++) {
|
||||
//draw selected index background
|
||||
if (i == pressI) {
|
||||
canvas.drawCircle(
|
||||
(float) mWidth / 2,
|
||||
t + mGapHeight * (i + 0.5f),
|
||||
(float) Math.min(mWidth, mGapHeight) / 2,
|
||||
backgroundPaint);
|
||||
mPaint.setColor(textColorPressed);
|
||||
} else {
|
||||
mPaint.setColor(textColor);
|
||||
}
|
||||
index = mIndexDataList.get(i);
|
||||
Paint.FontMetrics fontMetrics =
|
||||
mPaint.getFontMetrics(); //get FontMetrics of paint,y for drawText mean text baseLine
|
||||
int baseline =
|
||||
(int)
|
||||
((mGapHeight - fontMetrics.bottom - fontMetrics.top)
|
||||
/ 2); //get every index rect,baseline on vertical central
|
||||
canvas.drawText(
|
||||
index,
|
||||
(float) mWidth / 2 - mPaint.measureText(index) / 2,
|
||||
t + mGapHeight * i + baseline,
|
||||
mPaint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performClick() {
|
||||
return super.performClick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
setBackgroundColor(mPressedBackground);
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
float y = event.getY();
|
||||
pressI = (int) ((y - getPaddingTop()) / mGapHeight);
|
||||
if (pressI < 0) {
|
||||
pressI = 0;
|
||||
} else if (pressI >= mIndexDataList.size()) {
|
||||
pressI = mIndexDataList.size() - 1;
|
||||
}
|
||||
if (null != mOnIndexPressedListener && pressI > -1 && pressI < mIndexDataList.size()) {
|
||||
mOnIndexPressedListener.onIndexPressed(pressI, mIndexDataList.get(pressI));
|
||||
invalidate();
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
performClick();
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
default:
|
||||
setBackgroundResource(android.R.color.transparent); //set transparent when up
|
||||
if (null != mOnIndexPressedListener) {
|
||||
mOnIndexPressedListener.onMotionEventEnd();
|
||||
}
|
||||
pressI = -1;
|
||||
invalidate();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldW, int oldH) {
|
||||
super.onSizeChanged(w, h, oldW, oldH);
|
||||
mWidth = w;
|
||||
mHeight = h;
|
||||
if (null == mIndexDataList || mIndexDataList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
computeGapHeight();
|
||||
}
|
||||
|
||||
public onIndexPressedListener getOnIndexPressedListener() {
|
||||
return mOnIndexPressedListener;
|
||||
}
|
||||
|
||||
public void setOnIndexPressedListener(onIndexPressedListener mOnIndexPressedListener) {
|
||||
this.mOnIndexPressedListener = mOnIndexPressedListener;
|
||||
}
|
||||
|
||||
public IndexBar setPressedShowTextView(TextView mPressedShowTextView) {
|
||||
this.mPressedShowTextView = mPressedShowTextView;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IndexBar setLayoutManager(LinearLayoutManager mLayoutManager) {
|
||||
this.mLayoutManager = mLayoutManager;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** must been invoked before {@link #setSourceData(List)} */
|
||||
public IndexBar setNeedRealIndex(boolean needRealIndex) {
|
||||
isNeedRealIndex = needRealIndex;
|
||||
initIndexData();
|
||||
return this;
|
||||
}
|
||||
|
||||
private void initIndexData() {
|
||||
if (isNeedRealIndex) {
|
||||
mIndexDataList = new ArrayList<>();
|
||||
} else {
|
||||
mIndexDataList = Arrays.asList(INDEX_STRING);
|
||||
}
|
||||
}
|
||||
|
||||
public IndexBar setSourceData(List<? extends IndexPinyinBean> mSourceDatas) {
|
||||
this.mSourceData = mSourceDatas;
|
||||
initSourceData();
|
||||
return this;
|
||||
}
|
||||
|
||||
/** init source data and get index data */
|
||||
private void initSourceData() {
|
||||
if (null == mSourceData || mSourceData.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (!isSourceDataAlreadySorted) {
|
||||
//sort sourceData
|
||||
mDataHelper.sortSourceData(mSourceData);
|
||||
} else {
|
||||
mDataHelper.convert(mSourceData);
|
||||
mDataHelper.fillIndexTag(mSourceData);
|
||||
}
|
||||
if (isNeedRealIndex) {
|
||||
mDataHelper.getSortedIndexData(mSourceData, mIndexDataList);
|
||||
computeGapHeight();
|
||||
}
|
||||
}
|
||||
|
||||
/** invoked when: 1 data changed 2 size changed get gapHeight */
|
||||
private void computeGapHeight() {
|
||||
mGapHeight = (mHeight - getPaddingTop() - getPaddingBottom()) / mIndexDataList.size();
|
||||
}
|
||||
|
||||
private int getPosByTag(String tag) {
|
||||
if (null == mSourceData || mSourceData.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
if (TextUtils.isEmpty(tag)) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < mSourceData.size(); i++) {
|
||||
if (tag.equals(mSourceData.get(i).getIndexTag())) {
|
||||
return i + getHeaderViewCount();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** on index pressed listener */
|
||||
public interface onIndexPressedListener {
|
||||
void onIndexPressed(int index, String text);
|
||||
|
||||
void onMotionEventEnd(); //(UP CANCEL)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.indexbar.bean;
|
||||
|
||||
import com.netease.yunxin.kit.contactkit.ui.indexbar.suspension.ISuspension;
|
||||
import java.io.Serializable;
|
||||
|
||||
/** base bean for index */
|
||||
public abstract class IndexBean implements ISuspension, Serializable {
|
||||
|
||||
private String indexTag; //tag of index (show in the top)
|
||||
|
||||
public String getIndexTag() {
|
||||
return indexTag;
|
||||
}
|
||||
|
||||
public IndexBean setIndexTag(String baseIndexTag) {
|
||||
this.indexTag = baseIndexTag;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return indexTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowDivision() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.indexbar.bean;
|
||||
|
||||
/** index pinyin bean */
|
||||
public abstract class IndexPinyinBean extends IndexBean {
|
||||
|
||||
private String indexPinyin;
|
||||
|
||||
public String getIndexPinyin() {
|
||||
return indexPinyin;
|
||||
}
|
||||
|
||||
public IndexPinyinBean setIndexPinyin(String indexPinyin) {
|
||||
this.indexPinyin = indexPinyin;
|
||||
return this;
|
||||
}
|
||||
|
||||
//is need to translate as pinyin
|
||||
public boolean isNeedToPinyin() {
|
||||
return false;
|
||||
}
|
||||
|
||||
//get target String
|
||||
public abstract String getTarget();
|
||||
|
||||
@Override
|
||||
public boolean isSuspension() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.indexbar.helper;
|
||||
|
||||
import com.netease.yunxin.kit.contactkit.ui.indexbar.bean.IndexPinyinBean;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* helper for indexBar and data 1 translate Chinese characters to pinyin 2 fill indexTag 3 sort
|
||||
* source data 4 source data after sort->indexBar source data
|
||||
*/
|
||||
public interface IIndexBarDataHelper {
|
||||
//translate Chinese characters to pinyin
|
||||
IIndexBarDataHelper convert(List<? extends IndexPinyinBean> data);
|
||||
|
||||
//pinyin->tag
|
||||
IIndexBarDataHelper fillIndexTag(List<? extends IndexPinyinBean> data);
|
||||
|
||||
//sort source data
|
||||
IIndexBarDataHelper sortSourceData(List<? extends IndexPinyinBean> data);
|
||||
|
||||
//sort the data for indexBar,call after sortSourceData
|
||||
IIndexBarDataHelper getSortedIndexData(
|
||||
List<? extends IndexPinyinBean> sourceData, List<String> data);
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.indexbar.helper;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import com.github.promeg.pinyinhelper.Pinyin;
|
||||
import com.netease.yunxin.kit.contactkit.ui.indexbar.bean.IndexPinyinBean;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class IndexBarDataHelperImpl implements IIndexBarDataHelper {
|
||||
/** if need Chinese Character -> Pinyin */
|
||||
@Override
|
||||
public IIndexBarDataHelper convert(List<? extends IndexPinyinBean> data) {
|
||||
if (null == data || data.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
int size = data.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
IndexPinyinBean indexPinyinBean = data.get(i);
|
||||
StringBuilder pySb = new StringBuilder();
|
||||
if (indexPinyinBean.isNeedToPinyin()) {
|
||||
String target = indexPinyinBean.getTarget();
|
||||
for (int i1 = 0; i1 < target.length(); i1++) {
|
||||
pySb.append(Pinyin.toPinyin(target.charAt(i1)).toUpperCase());
|
||||
}
|
||||
indexPinyinBean.setIndexPinyin(pySb.toString()); //设置城市名全拼音
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/** 如果需要取出,则 取出首字母->tag,或者特殊字母 "#". 否则,用户已经实现设置好 */
|
||||
@Override
|
||||
public IIndexBarDataHelper fillIndexTag(List<? extends IndexPinyinBean> dataList) {
|
||||
if (null == dataList || dataList.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
int size = dataList.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
IndexPinyinBean indexPinyinBean = dataList.get(i);
|
||||
if (indexPinyinBean.isNeedToPinyin()) {
|
||||
//以下代码设置城市拼音首字母
|
||||
if (TextUtils.isEmpty(indexPinyinBean.getIndexPinyin())) {
|
||||
indexPinyinBean.setIndexTag("#");
|
||||
continue;
|
||||
}
|
||||
String tagString = indexPinyinBean.getIndexPinyin().substring(0, 1);
|
||||
if (tagString.matches("[A-Z]")) { //如果是A-Z字母开头
|
||||
indexPinyinBean.setIndexTag(tagString);
|
||||
} else { //特殊字母这里统一用#处理
|
||||
indexPinyinBean.setIndexTag("#");
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IIndexBarDataHelper sortSourceData(List<? extends IndexPinyinBean> data) {
|
||||
if (null == data || data.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
convert(data);
|
||||
fillIndexTag(data);
|
||||
//对数据源进行排序
|
||||
Collections.sort(
|
||||
data,
|
||||
(Comparator<IndexPinyinBean>)
|
||||
(lhs, rhs) -> {
|
||||
if (!lhs.isNeedToPinyin()) {
|
||||
return 0;
|
||||
} else if (!rhs.isNeedToPinyin()) {
|
||||
return 0;
|
||||
} else if (lhs.getIndexTag().equals("#") && !rhs.getIndexTag().equals("#")) {
|
||||
return 1;
|
||||
} else if (!lhs.getIndexTag().equals("#") && rhs.getIndexTag().equals("#")) {
|
||||
return -1;
|
||||
} else {
|
||||
String lhsIndexTag = lhs.getIndexTag();
|
||||
String rhsIndexTag = rhs.getIndexTag();
|
||||
if (lhsIndexTag.equals("#") && rhsIndexTag.equals("#")) {
|
||||
String lhsFirst = lhs.getIndexPinyin().substring(0, 1);
|
||||
String rhsFirst = rhs.getIndexPinyin().substring(0, 1);
|
||||
if (TextUtils.isDigitsOnly(lhsFirst) && !TextUtils.isDigitsOnly(rhsFirst)) {
|
||||
return -1;
|
||||
} else if (!TextUtils.isDigitsOnly(lhsFirst)
|
||||
&& TextUtils.isDigitsOnly(rhsFirst)) {
|
||||
return 1;
|
||||
} else {
|
||||
return lhs.getIndexPinyin().compareTo(rhs.getIndexPinyin());
|
||||
}
|
||||
} else {
|
||||
return lhs.getIndexPinyin().compareTo(rhs.getIndexPinyin());
|
||||
}
|
||||
}
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IIndexBarDataHelper getSortedIndexData(
|
||||
List<? extends IndexPinyinBean> sourceData, List<String> data) {
|
||||
if (null == sourceData || sourceData.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
int size = sourceData.size();
|
||||
String baseIndexTag;
|
||||
for (int i = 0; i < size; i++) {
|
||||
baseIndexTag = sourceData.get(i).getIndexTag();
|
||||
if (!data.contains(baseIndexTag)) {
|
||||
data.add(baseIndexTag);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.indexbar.suspension;
|
||||
|
||||
/** suspension interface */
|
||||
public interface ISuspension {
|
||||
|
||||
boolean isSuspension();
|
||||
|
||||
boolean isShowDivision();
|
||||
|
||||
String getTag();
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.indexbar.suspension;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import java.util.List;
|
||||
|
||||
/** custom decoration for Suspension */
|
||||
public class SuspensionDecoration extends RecyclerView.ItemDecoration {
|
||||
|
||||
private static final int DEFAULT_COLOR_TITLE_BOTTOM_LINE_COLOR_RES = R.color.color_dbe0e8;
|
||||
|
||||
private static final int DEFAULT_INDEX_DECORATION_BG_RES = R.color.color_eff1f4;
|
||||
|
||||
private int colorTitleBg;
|
||||
private int colorTitleBottomLine;
|
||||
private int colorTitleFont;
|
||||
private int indexDecorationBg;
|
||||
private int mTitleFontSize;
|
||||
private int bottomLineHeight;
|
||||
private List<? extends ISuspension> mData;
|
||||
private final Paint mPaint;
|
||||
private final Rect mBounds; //rect for restore text for measure
|
||||
private int mTitleHeight;
|
||||
private int mHeaderViewCount = 0;
|
||||
|
||||
private float paddingLeft;
|
||||
private boolean showTagOffset = true;
|
||||
private boolean isFirstTagDraw = true;
|
||||
private boolean titleAlignBottom = false;
|
||||
private final int indexDecorationHeight;
|
||||
|
||||
public SuspensionDecoration(Context context, List<? extends ISuspension> datas) {
|
||||
super();
|
||||
mData = datas;
|
||||
mPaint = new Paint();
|
||||
mBounds = new Rect();
|
||||
colorTitleBg = context.getResources().getColor(R.color.color_ffffff);
|
||||
colorTitleBottomLine =
|
||||
context.getResources().getColor(DEFAULT_COLOR_TITLE_BOTTOM_LINE_COLOR_RES);
|
||||
colorTitleFont = context.getResources().getColor(R.color.color_b3b7bc);
|
||||
indexDecorationBg = context.getResources().getColor(DEFAULT_INDEX_DECORATION_BG_RES);
|
||||
mTitleHeight =
|
||||
(int)
|
||||
TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP, 33f, context.getResources().getDisplayMetrics());
|
||||
indexDecorationHeight =
|
||||
(int)
|
||||
TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP, 6f, context.getResources().getDisplayMetrics());
|
||||
mTitleFontSize =
|
||||
(int)
|
||||
TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_SP, 14f, context.getResources().getDisplayMetrics());
|
||||
bottomLineHeight =
|
||||
(int)
|
||||
TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP, 1f, context.getResources().getDisplayMetrics());
|
||||
mPaint.setTextSize(mTitleFontSize);
|
||||
mPaint.setAntiAlias(true);
|
||||
}
|
||||
|
||||
public SuspensionDecoration setTitleHeight(int mTitleHeight) {
|
||||
this.mTitleHeight = mTitleHeight;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuspensionDecoration setBottomLineHeight(int bottomLineHeight) {
|
||||
this.bottomLineHeight = bottomLineHeight;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuspensionDecoration setIndexDecorationBg(int indexDecorationBg) {
|
||||
this.indexDecorationBg = indexDecorationBg;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuspensionDecoration setColorTitleBg(int colorTitleBg) {
|
||||
this.colorTitleBg = colorTitleBg;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuspensionDecoration setColorTitleFont(int colorTitleFont) {
|
||||
this.colorTitleFont = colorTitleFont;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuspensionDecoration setTitleFontSize(int mTitleFontSize) {
|
||||
this.mTitleFontSize = mTitleFontSize;
|
||||
mPaint.setTextSize(mTitleFontSize);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuspensionDecoration setColorTitleBottomLine(int colorTitleBottomLine) {
|
||||
this.colorTitleBottomLine = colorTitleBottomLine;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuspensionDecoration setPaddingLeft(float paddingLeft) {
|
||||
this.paddingLeft = paddingLeft;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuspensionDecoration setTitleAlignBottom(boolean align) {
|
||||
this.titleAlignBottom = align;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuspensionDecoration setData(List<? extends ISuspension> mData) {
|
||||
this.mData = mData;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuspensionDecoration setShowTagOff(boolean show) {
|
||||
this.showTagOffset = show;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getHeaderViewCount() {
|
||||
return mHeaderViewCount;
|
||||
}
|
||||
|
||||
public SuspensionDecoration setHeaderViewCount(int headerViewCount) {
|
||||
mHeaderViewCount = headerViewCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(
|
||||
@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
|
||||
super.onDraw(c, parent, state);
|
||||
final int left = parent.getPaddingLeft();
|
||||
final int right = parent.getWidth() - parent.getPaddingRight();
|
||||
final int childCount = parent.getChildCount();
|
||||
isFirstTagDraw = true;
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
final View child = parent.getChildAt(i);
|
||||
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
|
||||
int position = params.getViewLayoutPosition();
|
||||
position -= getHeaderViewCount();
|
||||
if (mData == null
|
||||
|| mData.isEmpty()
|
||||
|| position > mData.size() - 1
|
||||
|| position < 0
|
||||
|| !mData.get(position).isShowDivision()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (position == 0) { //if 0 must have title
|
||||
drawTitleArea(c, left, right, child, params, position);
|
||||
} else {
|
||||
if (null != mData.get(position).getTag()
|
||||
&& !mData.get(position).getTag().equals(mData.get(position - 1).getTag())) {
|
||||
//not empty and different with pre
|
||||
drawTitleArea(c, left, right, child, params, position);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** draw title area */
|
||||
private void drawTitleArea(
|
||||
Canvas c,
|
||||
int left,
|
||||
int right,
|
||||
View child,
|
||||
RecyclerView.LayoutParams params,
|
||||
int position) { //最先调用,绘制在最下层
|
||||
if (isFirstTagDraw) {
|
||||
mPaint.setColor(indexDecorationBg);
|
||||
c.drawRect(
|
||||
left,
|
||||
child.getTop() - params.topMargin - mTitleHeight - indexDecorationHeight,
|
||||
right,
|
||||
child.getTop() - params.topMargin - mTitleHeight,
|
||||
mPaint);
|
||||
}
|
||||
isFirstTagDraw = false;
|
||||
|
||||
mPaint.setColor(colorTitleBg);
|
||||
c.drawRect(
|
||||
left,
|
||||
child.getTop() - params.topMargin - mTitleHeight,
|
||||
right,
|
||||
child.getTop() - params.topMargin,
|
||||
mPaint);
|
||||
|
||||
mPaint.setColor(colorTitleBottomLine);
|
||||
c.drawRect(
|
||||
left + paddingLeft,
|
||||
child.getTop() - params.topMargin - bottomLineHeight,
|
||||
right,
|
||||
child.getTop() - params.topMargin,
|
||||
mPaint);
|
||||
|
||||
mPaint.setColor(colorTitleFont);
|
||||
mPaint.getTextBounds(
|
||||
mData.get(position).getTag(), 0, mData.get(position).getTag().length(), mBounds);
|
||||
c.drawText(
|
||||
mData.get(position).getTag(),
|
||||
child.getPaddingLeft() + paddingLeft,
|
||||
child.getTop()
|
||||
- params.topMargin
|
||||
- (titleAlignBottom ? 0 : ((float) mTitleHeight / 2 - (float) mBounds.height() / 2)),
|
||||
mPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDrawOver(
|
||||
@NonNull Canvas c, final RecyclerView parent, @NonNull RecyclerView.State state) {
|
||||
if (parent.getLayoutManager() == null) {
|
||||
return;
|
||||
}
|
||||
int pos = ((LinearLayoutManager) (parent.getLayoutManager())).findFirstVisibleItemPosition();
|
||||
pos -= getHeaderViewCount();
|
||||
if (mData == null
|
||||
|| mData.isEmpty()
|
||||
|| pos > mData.size() - 1
|
||||
|| pos < 0
|
||||
|| !mData.get(pos).isSuspension()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String tag = mData.get(pos).getTag();
|
||||
RecyclerView.ViewHolder viewHolder =
|
||||
parent.findViewHolderForLayoutPosition(pos + getHeaderViewCount());
|
||||
if (viewHolder == null) {
|
||||
return;
|
||||
}
|
||||
View child = viewHolder.itemView;
|
||||
boolean flag = false; //flag for canvas have moved
|
||||
if ((pos + 1) < mData.size()) {
|
||||
if (null != tag && !tag.equals(mData.get(pos + 1).getTag())) {
|
||||
if (child.getHeight() + child.getTop() < mTitleHeight) {
|
||||
c.save();
|
||||
flag = true;
|
||||
|
||||
c.translate(0, child.getHeight() + child.getTop() - mTitleHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
mPaint.setColor(colorTitleBg);
|
||||
c.drawRect(
|
||||
parent.getPaddingLeft(),
|
||||
parent.getPaddingTop(),
|
||||
parent.getRight() - parent.getPaddingRight(),
|
||||
parent.getPaddingTop() + mTitleHeight,
|
||||
mPaint);
|
||||
mPaint.setColor(colorTitleFont);
|
||||
mPaint.getTextBounds(tag, 0, tag == null ? 0 : tag.length(), mBounds);
|
||||
c.drawText(
|
||||
tag,
|
||||
child.getPaddingLeft() + 40,
|
||||
parent.getPaddingTop()
|
||||
+ mTitleHeight
|
||||
- (titleAlignBottom ? 0 : ((float) mTitleHeight / 2 - (float) mBounds.height() / 2)),
|
||||
mPaint);
|
||||
if (flag) c.restore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getItemOffsets(
|
||||
@NonNull Rect outRect,
|
||||
@NonNull View view,
|
||||
@NonNull RecyclerView parent,
|
||||
@NonNull RecyclerView.State state) {
|
||||
super.getItemOffsets(outRect, view, parent, state);
|
||||
int position = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition();
|
||||
position -= getHeaderViewCount();
|
||||
if (mData == null || mData.isEmpty() || position > mData.size() - 1) {
|
||||
return;
|
||||
}
|
||||
if (position >= 0) {
|
||||
ISuspension titleCategoryInterface = mData.get(position);
|
||||
if (titleCategoryInterface.isShowDivision()) {
|
||||
if (position == 0) {
|
||||
outRect.set(0, mTitleHeight + (showTagOffset ? indexDecorationHeight : 0), 0, 0);
|
||||
} else {
|
||||
if (null != titleCategoryInterface.getTag()
|
||||
&& !titleCategoryInterface.getTag().equals(mData.get(position - 1).getTag())) {
|
||||
outRect.set(0, mTitleHeight + (showTagOffset ? indexDecorationHeight : 0), 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.interfaces;
|
||||
|
||||
import android.util.SparseArray;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListView;
|
||||
|
||||
/** Actions for default ViewHolder in {@link ContactListView} */
|
||||
public class ContactActions {
|
||||
|
||||
private final SparseArray<IContactClickListener> itemClickListeners;
|
||||
|
||||
private final SparseArray<IContactSelectorListener> itemSelectorListeners;
|
||||
|
||||
public ContactActions() {
|
||||
itemClickListeners = new SparseArray<>();
|
||||
itemSelectorListeners = new SparseArray<>();
|
||||
}
|
||||
|
||||
public void addSelectorListener(int viewType, IContactSelectorListener selectorListener) {
|
||||
itemSelectorListeners.put(viewType, selectorListener);
|
||||
}
|
||||
|
||||
public void addContactListener(int viewType, IContactClickListener contactListener) {
|
||||
itemClickListeners.put(viewType, contactListener);
|
||||
}
|
||||
|
||||
public IContactClickListener getContactListener(int viewType) {
|
||||
return itemClickListeners.get(viewType);
|
||||
}
|
||||
|
||||
public IContactSelectorListener getSelectorListener(int viewType) {
|
||||
return itemSelectorListeners.get(viewType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.interfaces;
|
||||
|
||||
public interface IContactCallback {
|
||||
|
||||
void updateUnreadCount(int count);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.interfaces;
|
||||
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
|
||||
/** Action listener */
|
||||
public interface IContactClickListener {
|
||||
|
||||
/** on item click */
|
||||
void onClick(int position, BaseContactBean data);
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.interfaces;
|
||||
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactTeamBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* when data have changed,you can user this interface post data to {@link ContactListView}
|
||||
*/
|
||||
public interface IContactDataChanged {
|
||||
|
||||
/**
|
||||
* Contacts friend data have changed
|
||||
*/
|
||||
void onFriendDataSourceChanged(List<ContactFriendBean> contactItemBeanList);
|
||||
|
||||
/**
|
||||
* add one friend data
|
||||
*
|
||||
* @param friend friend data,this data will been sort
|
||||
*/
|
||||
void addFriendData(List<ContactFriendBean> friend);
|
||||
|
||||
void insertFrindData(int index, ContactFriendBean friendBean);
|
||||
|
||||
void updateGroupData(ContactTeamBean teamBeans);
|
||||
|
||||
/**
|
||||
* remove one friend data
|
||||
*
|
||||
* @param friend friend data,data will been sort
|
||||
*/
|
||||
void removeFriendData(List<ContactFriendBean> friend);
|
||||
|
||||
/**
|
||||
* update one friend data
|
||||
*
|
||||
* @param friend friend data,data will been sort
|
||||
*/
|
||||
void updateFriendData(List<ContactFriendBean> friend);
|
||||
|
||||
/**
|
||||
* update data which have been added
|
||||
*
|
||||
* @param data any data instanceof BaseContactBean except Friend
|
||||
*/
|
||||
void updateContactData(BaseContactBean data);
|
||||
|
||||
/**
|
||||
* update data as list(remove all this type data and add new data)
|
||||
*
|
||||
* @param viewType the viewType been update
|
||||
* @param data any data instanceof BaseContactBean except Friends
|
||||
*/
|
||||
void updateContactData(int viewType, List<? extends BaseContactBean> data);
|
||||
|
||||
/**
|
||||
* add a custom data
|
||||
*/
|
||||
void addContactData(BaseContactBean contactData);
|
||||
|
||||
/**
|
||||
* add custom data as list
|
||||
*/
|
||||
void addContactData(List<? extends BaseContactBean> contactData);
|
||||
|
||||
/**
|
||||
* remove custom data
|
||||
*/
|
||||
void removeContactData(BaseContactBean contactData);
|
||||
|
||||
/**
|
||||
* remove custom as list
|
||||
*/
|
||||
void removeContactData(List<? extends BaseContactBean> contactData);
|
||||
|
||||
/**
|
||||
* clear data
|
||||
*/
|
||||
void clearContactData();
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.interfaces;
|
||||
|
||||
import com.netease.yunxin.kit.contactkit.ui.IContactFactory;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListViewAttrs;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.adapter.ContactAdapter;
|
||||
|
||||
public interface IContactListView {
|
||||
|
||||
//******************interaction*************
|
||||
|
||||
/**
|
||||
* set action for Contact
|
||||
*
|
||||
* @param contactActions actions
|
||||
*/
|
||||
void setContactAction(ContactActions contactActions);
|
||||
|
||||
//******************ui display*************
|
||||
|
||||
/** get adapter in ContactListView */
|
||||
ContactAdapter getAdapter();
|
||||
|
||||
/**
|
||||
* if you want add your owner viewHolder,you should set your owner factory here
|
||||
*
|
||||
* @param viewHolderFactory your owner ContactViewHolderFactory
|
||||
*/
|
||||
void setViewHolderFactory(IContactFactory viewHolderFactory);
|
||||
|
||||
/**
|
||||
* set config for ContactListView
|
||||
*
|
||||
* @param attrs config
|
||||
*/
|
||||
void setViewConfig(ContactListViewAttrs attrs);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.interfaces;
|
||||
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
|
||||
/** Action listener */
|
||||
public interface IContactSelectorListener {
|
||||
|
||||
/** on item click */
|
||||
void onSelector(boolean selector, BaseContactBean data);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.interfaces;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListView;
|
||||
|
||||
/** attrs for {@link ContactListView} */
|
||||
public interface IContactViewAttrs {
|
||||
|
||||
/** set textColor for Name */
|
||||
void setTitleColor(@ColorInt int color);
|
||||
|
||||
/**
|
||||
* show indexBar or not
|
||||
*
|
||||
* @param show show if true
|
||||
*/
|
||||
void showIndexBar(boolean show);
|
||||
|
||||
/**
|
||||
* show selector
|
||||
*
|
||||
* @param show show selector if true
|
||||
*/
|
||||
void showSelector(boolean show);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.model;
|
||||
|
||||
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
|
||||
import com.netease.yunxin.kit.contactkit.ui.indexbar.bean.IndexPinyinBean;
|
||||
|
||||
public abstract class BaseContactBean extends IndexPinyinBean {
|
||||
|
||||
/** viewType {@link IViewTypeConstant} for data */
|
||||
public int viewType;
|
||||
|
||||
/** router for item click */
|
||||
public String router;
|
||||
|
||||
/** start as 0, weight bigger means item will show higher 0 for Friends Data */
|
||||
public int weight;
|
||||
|
||||
public MsgAttachment attachment;
|
||||
|
||||
public MsgAttachment getAttachment() {
|
||||
return attachment;
|
||||
}
|
||||
|
||||
public void setAttachment(MsgAttachment attachment) {
|
||||
this.attachment = attachment;
|
||||
}
|
||||
|
||||
public interface ContactBeanWeight {
|
||||
/** base weight,for friend item */
|
||||
int BASE_WEIGHT = 0;
|
||||
|
||||
/** weight for entrance */
|
||||
int ENTRANCE_WEIGHT = 50;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.model;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.model.UserInfo;
|
||||
|
||||
/**
|
||||
* data bean for friend
|
||||
*/
|
||||
public class ContactBlackListBean extends BaseContactBean {
|
||||
|
||||
public UserInfo data;
|
||||
public FriendInfo friendInfo;
|
||||
|
||||
|
||||
|
||||
public ContactBlackListBean(UserInfo data) {
|
||||
this.data = data;
|
||||
viewType = IViewTypeConstant.CONTACT_BLACK_LIST;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
||||
if (friendInfo != null && !TextUtils.isEmpty(friendInfo.getAlias())) {
|
||||
return friendInfo.getAlias();
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(data.getName())) {
|
||||
return data.getName();
|
||||
}
|
||||
return data.getAccount();
|
||||
}
|
||||
|
||||
public String getAvatarName() {
|
||||
if (!TextUtils.isEmpty(data.getName())) {
|
||||
return data.getName();
|
||||
}
|
||||
return data.getAccount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowDivision() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTarget() {
|
||||
return data.getName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.model;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import java.util.Objects;
|
||||
|
||||
/** Contact data for default ViewHolder */
|
||||
public class ContactEntranceBean extends BaseContactBean {
|
||||
public @DrawableRes int icon;
|
||||
|
||||
public int number;
|
||||
|
||||
public boolean showRightArrow = true;
|
||||
|
||||
public String title;
|
||||
|
||||
public ContactEntranceBean(@DrawableRes int icon, @NonNull String title) {
|
||||
this.icon = icon;
|
||||
this.title = title;
|
||||
weight = ContactBeanWeight.ENTRANCE_WEIGHT;
|
||||
viewType = IViewTypeConstant.CONTACT_ACTION_ENTER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ContactEntranceBean that = (ContactEntranceBean) o;
|
||||
return icon == that.icon && Objects.equals(title, that.title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(icon, title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowDivision() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTarget() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.model;
|
||||
|
||||
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
|
||||
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
|
||||
import com.netease.yunxin.kit.chatkit.model.ConversationInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendInfo;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* data bean for friend
|
||||
*/
|
||||
public class ContactFriendBean extends BaseContactBean {
|
||||
|
||||
public FriendInfo data;
|
||||
public String conversationText;
|
||||
public String conversationTime;
|
||||
public MsgTypeEnum msgTypeEnum;
|
||||
public MsgAttachment msgAttachment;
|
||||
// public ConversationInfo conversationInfo;
|
||||
public long time = 0;
|
||||
|
||||
public MsgAttachment getMsgAttachment() {
|
||||
return msgAttachment;
|
||||
}
|
||||
|
||||
public void setMsgAttachment(MsgAttachment msgAttachment) {
|
||||
this.msgAttachment = msgAttachment;
|
||||
}
|
||||
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(long time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public MsgTypeEnum getMsgTypeEnum() {
|
||||
return msgTypeEnum;
|
||||
}
|
||||
|
||||
public void setMsgTypeEnum(MsgTypeEnum msgTypeEnum) {
|
||||
this.msgTypeEnum = msgTypeEnum;
|
||||
}
|
||||
|
||||
// public ConversationInfo getConversationInfo() {
|
||||
// return conversationInfo;
|
||||
// }
|
||||
//
|
||||
// public void setConversationInfo(ConversationInfo conversationInfo) {
|
||||
// this.conversationInfo = conversationInfo;
|
||||
// }
|
||||
|
||||
|
||||
public boolean isSelected;
|
||||
|
||||
public boolean cannotSelected;
|
||||
|
||||
public String getConversationText() {
|
||||
return conversationText;
|
||||
}
|
||||
|
||||
public void setConversationText(String conversationText) {
|
||||
this.conversationText = conversationText;
|
||||
}
|
||||
|
||||
public String getConversationTime() {
|
||||
return conversationTime;
|
||||
}
|
||||
|
||||
public void setConversationTime(String conversationTime) {
|
||||
this.conversationTime = conversationTime;
|
||||
}
|
||||
|
||||
public ContactFriendBean(FriendInfo data) {
|
||||
this.data = data;
|
||||
weight = ContactBeanWeight.BASE_WEIGHT;
|
||||
viewType = IViewTypeConstant.CONTACT_FRIEND;
|
||||
}
|
||||
|
||||
public boolean isSelected() {
|
||||
return isSelected;
|
||||
}
|
||||
|
||||
public boolean isCannotSelected() {
|
||||
return cannotSelected;
|
||||
}
|
||||
|
||||
public void setCannotSelected(boolean cannotSelected) {
|
||||
this.cannotSelected = cannotSelected;
|
||||
}
|
||||
|
||||
public void setSelected(boolean selected) {
|
||||
isSelected = selected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNeedToPinyin() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowDivision() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTarget() {
|
||||
return data.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ContactFriendBean that = (ContactFriendBean) o;
|
||||
return this.data.equals(that.data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.model;
|
||||
|
||||
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
|
||||
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
|
||||
import com.netease.nimlib.sdk.team.model.Team;
|
||||
import com.netease.yunxin.kit.chatkit.model.ConversationInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
|
||||
/**
|
||||
* Contact data for team
|
||||
*/
|
||||
public class ContactTeamBean extends BaseContactBean {
|
||||
|
||||
public String content;
|
||||
public Team data;
|
||||
public long conversationTime;
|
||||
public String time;
|
||||
public MsgTypeEnum msgTypeEnum;
|
||||
public MsgAttachment msgAttachment;
|
||||
public String fromNick;
|
||||
public String fromAccount;
|
||||
|
||||
public String getFromNick() {
|
||||
return fromNick;
|
||||
}
|
||||
|
||||
public void setFromNick(String fromNick) {
|
||||
this.fromNick = fromNick;
|
||||
}
|
||||
|
||||
public String getFromAccount() {
|
||||
return fromAccount;
|
||||
}
|
||||
|
||||
public void setFromAccount(String fromAccount) {
|
||||
this.fromAccount = fromAccount;
|
||||
}
|
||||
|
||||
public MsgTypeEnum getMsgTypeEnum() {
|
||||
return msgTypeEnum;
|
||||
}
|
||||
|
||||
public void setMsgTypeEnum(MsgTypeEnum msgTypeEnum) {
|
||||
this.msgTypeEnum = msgTypeEnum;
|
||||
}
|
||||
|
||||
public MsgAttachment getMsgAttachment() {
|
||||
return msgAttachment;
|
||||
}
|
||||
|
||||
public void setMsgAttachment(MsgAttachment msgAttachment) {
|
||||
this.msgAttachment = msgAttachment;
|
||||
}
|
||||
|
||||
public String getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(String time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
// public ConversationInfo getConversationInfo() {
|
||||
// return conversationInfo;
|
||||
// }
|
||||
//
|
||||
// public void setConversationInfo(ConversationInfo conversationInfo) {
|
||||
// this.conversationInfo = conversationInfo;
|
||||
// }
|
||||
|
||||
|
||||
public long getConversationTime() {
|
||||
return conversationTime;
|
||||
}
|
||||
|
||||
public void setConversationTime(long conversationTime) {
|
||||
this.conversationTime = conversationTime;
|
||||
}
|
||||
|
||||
public ContactTeamBean(Team data) {
|
||||
this.data = data;
|
||||
viewType = IViewTypeConstant.CONTACT_TEAM_LIST;
|
||||
this.router = RouterConstant.PATH_CHAT_TEAM_PAGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowDivision() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTarget() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.model;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.model.UserInfo;
|
||||
|
||||
/** profile page user info */
|
||||
public class ContactUserInfoBean {
|
||||
public UserInfo data;
|
||||
public FriendInfo friendInfo;
|
||||
public boolean isFriend;
|
||||
public boolean isBlack;
|
||||
public boolean messageNotify = true;
|
||||
|
||||
public ContactUserInfoBean(UserInfo user) {
|
||||
this.data = user;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
String name = data.getUserInfoName();
|
||||
if (friendInfo != null && !TextUtils.isEmpty(friendInfo.getAlias())) {
|
||||
name = friendInfo.getName();
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.model;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import com.netease.nimlib.sdk.friend.model.AddFriendNotify;
|
||||
import com.netease.yunxin.kit.corekit.im.model.SystemMessageInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.model.SystemMessageInfoStatus;
|
||||
import com.netease.yunxin.kit.corekit.im.model.SystemMessageInfoType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/** Contact data for verify data */
|
||||
public class ContactVerifyInfoBean extends BaseContactBean {
|
||||
|
||||
public SystemMessageInfo data;
|
||||
|
||||
public List<SystemMessageInfo> messageList = new ArrayList<>();
|
||||
|
||||
public ContactVerifyInfoBean(SystemMessageInfo data) {
|
||||
this.data = data;
|
||||
messageList.add(data);
|
||||
viewType = IViewTypeConstant.CONTACT_VERIFY_INFO;
|
||||
}
|
||||
|
||||
public ContactVerifyInfoBean(SystemMessageInfo data, List<SystemMessageInfo> list) {
|
||||
this.data = data;
|
||||
messageList.clear();
|
||||
messageList.add(data);
|
||||
if (list != null) {
|
||||
messageList.addAll(list);
|
||||
}
|
||||
viewType = IViewTypeConstant.CONTACT_VERIFY_INFO;
|
||||
}
|
||||
|
||||
public int getUnreadCount() {
|
||||
int count = 0;
|
||||
for (SystemMessageInfo messageInfo : messageList) {
|
||||
if (messageInfo.getUnread()) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public void clearUnreadCount() {
|
||||
for (SystemMessageInfo messageInfo : messageList) {
|
||||
if (messageInfo.getUnread()) {
|
||||
messageInfo.setUnread(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateStatus(SystemMessageInfoStatus status) {
|
||||
for (SystemMessageInfo messageInfo : messageList) {
|
||||
messageInfo.setInfoStatus(status);
|
||||
messageInfo.setUnread(false);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean pushMessageIfSame(SystemMessageInfo messageInfo) {
|
||||
if (isSameMessage(messageInfo)) {
|
||||
if (data.getTime() < messageInfo.getTime()) {
|
||||
data = messageInfo;
|
||||
}
|
||||
messageList.add(messageInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowDivision() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTarget() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isSameMessage(SystemMessageInfo messageInfo) {
|
||||
if (messageInfo == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (data.getInfoType() == messageInfo.getInfoType()
|
||||
&& TextUtils.equals(data.getFromAccount(), messageInfo.getFromAccount())
|
||||
&& TextUtils.equals(data.getTargetId(), messageInfo.getTargetId())
|
||||
&& data.getInfoStatus() == messageInfo.getInfoStatus()) {
|
||||
|
||||
if (messageInfo.getInfoType() == SystemMessageInfoType.AddFriend
|
||||
&& messageInfo.getAttachObject() instanceof AddFriendNotify) {
|
||||
|
||||
if (!(data.getAttachObject() instanceof AddFriendNotify)) {
|
||||
return false;
|
||||
}
|
||||
AddFriendNotify notify = (AddFriendNotify) data.getAttachObject();
|
||||
AddFriendNotify notifyInfo = (AddFriendNotify) messageInfo.getAttachObject();
|
||||
if (notify.getEvent() == notifyInfo.getEvent()
|
||||
&& TextUtils.equals(notify.getAccount(), notifyInfo.getAccount())) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof ContactVerifyInfoBean)) return false;
|
||||
ContactVerifyInfoBean infoBean = (ContactVerifyInfoBean) o;
|
||||
return isSameMessage(infoBean.data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.model;
|
||||
|
||||
/** constants view type 1~9 for default ViewHolder */
|
||||
public interface IViewTypeConstant {
|
||||
|
||||
/** friend */
|
||||
int CONTACT_FRIEND = 1;
|
||||
|
||||
/** entrance */
|
||||
int CONTACT_ACTION_ENTER = 2;
|
||||
|
||||
/** custom view type start with this */
|
||||
int CUSTOM_START = 10;
|
||||
|
||||
/** blackList */
|
||||
int CONTACT_BLACK_LIST = 11;
|
||||
|
||||
/** verify info */
|
||||
int CONTACT_VERIFY_INFO = 12;
|
||||
|
||||
/** group list */
|
||||
int CONTACT_TEAM_LIST = 13;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.model;
|
||||
|
||||
import com.netease.yunxin.kit.chatkit.model.FriendSearchInfo;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.BaseBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.ContactConstant;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import java.util.Objects;
|
||||
|
||||
public class SearchFriendBean extends BaseBean {
|
||||
private static final String TAG = "SearchFriendBean";
|
||||
public FriendSearchInfo friendSearchInfo;
|
||||
|
||||
public SearchFriendBean(FriendSearchInfo searchInfo, String router) {
|
||||
this.friendSearchInfo = searchInfo;
|
||||
this.viewType = ContactConstant.SearchViewType.USER;
|
||||
this.router = router;
|
||||
this.paramKey = RouterConstant.CHAT_KRY;
|
||||
this.param = searchInfo.getFriendInfo().getUserInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof SearchFriendBean)) return false;
|
||||
SearchFriendBean that = (SearchFriendBean) o;
|
||||
return Objects.equals(
|
||||
friendSearchInfo.getFriendInfo().getAccount(),
|
||||
that.friendSearchInfo.getFriendInfo().getAccount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(friendSearchInfo.getFriendInfo().getAccount());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.model;
|
||||
|
||||
import com.netease.yunxin.kit.chatkit.model.TeamSearchInfo;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.BaseBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.ContactConstant;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import java.util.Objects;
|
||||
|
||||
public class SearchTeamBean extends BaseBean {
|
||||
private static final String TAG = "SearchTeamBean";
|
||||
public TeamSearchInfo teamSearchInfo;
|
||||
|
||||
public SearchTeamBean(TeamSearchInfo searchInfo, String router) {
|
||||
this.teamSearchInfo = searchInfo;
|
||||
this.viewType = ContactConstant.SearchViewType.TEAM;
|
||||
this.router = router;
|
||||
this.paramKey = RouterConstant.CHAT_KRY;
|
||||
this.param = searchInfo.getTeam();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof SearchTeamBean)) return false;
|
||||
SearchTeamBean that = (SearchTeamBean) o;
|
||||
return Objects.equals(teamSearchInfo.getTeam().getId(), that.teamSearchInfo.getTeam().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(teamSearchInfo.getTeam().getId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.model;
|
||||
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.BaseBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.ContactConstant;
|
||||
|
||||
public class SearchTitleBean extends BaseBean {
|
||||
|
||||
public String title;
|
||||
public int titleRes;
|
||||
|
||||
public SearchTitleBean(String tt) {
|
||||
this.title = tt;
|
||||
this.viewType = ContactConstant.SearchViewType.TITLE;
|
||||
}
|
||||
|
||||
public SearchTitleBean(int res) {
|
||||
this.titleRes = res;
|
||||
this.viewType = ContactConstant.SearchViewType.TITLE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal;
|
||||
|
||||
import android.view.View;
|
||||
import com.netease.yunxin.kit.contactkit.ui.ContactUIConfig;
|
||||
import com.netease.yunxin.kit.contactkit.ui.FragmentBuilder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.interfaces.IContactClickListener;
|
||||
import com.netease.yunxin.kit.contactkit.ui.interfaces.IContactSelectorListener;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactEntranceBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.normal.contact.ContactFragment;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListViewAttrs;
|
||||
import java.util.List;
|
||||
|
||||
public class ContactFragmentBuilder extends FragmentBuilder {
|
||||
|
||||
ContactUIConfig contactConfig;
|
||||
|
||||
public ContactFragmentBuilder() {}
|
||||
|
||||
@Override
|
||||
public ContactFragment build() {
|
||||
ContactFragment fragment = new ContactFragment();
|
||||
if (contactConfig != null) {
|
||||
fragment.setContactConfig(contactConfig);
|
||||
}
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public void setContactConfig(ContactUIConfig contactConfig) {
|
||||
this.contactConfig = contactConfig;
|
||||
}
|
||||
|
||||
public ContactFragmentBuilder setShowTitleBar(boolean show) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.showTitleBar = show;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContactFragmentBuilder setTitle(String title) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContactFragmentBuilder setTitleColor(int color) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.titleColor = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContactFragmentBuilder setShowTitleBarRight2Icon(boolean show) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.showTitleBarRight2Icon = show;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContactFragmentBuilder setSearchIcon(int res) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.titleBarRight2Res = res;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContactFragmentBuilder setSearchClickListener(View.OnClickListener listener) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.titleBarRight2Click = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContactFragmentBuilder setShowMoreIcon(boolean show) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.showTitleBarRightIcon = show;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContactFragmentBuilder setMoreIcon(int res) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.titleBarRightRes = res;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContactFragmentBuilder setMoreClickListener(View.OnClickListener listener) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.titleBarRightClick = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContactFragmentBuilder showHeader(boolean show) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.showHeader = show;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContactFragmentBuilder setContactListViewAttar(ContactListViewAttrs attrs) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.contactAttrs = attrs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContactFragmentBuilder setHeaderData(List<ContactEntranceBean> data) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.headerData = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContactFragmentBuilder setContactClickListener(
|
||||
int type, IContactClickListener contactListener) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.itemClickListeners.put(type, contactListener);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContactFragmentBuilder setContactSelection(
|
||||
int type, IContactSelectorListener contactListener) {
|
||||
if (contactConfig == null) {
|
||||
contactConfig = new ContactUIConfig();
|
||||
}
|
||||
contactConfig.itemSelectorListeners.put(type, contactListener);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.addfriend;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import com.netease.yunxin.kit.contactkit.ui.addfriend.BaseAddFriendActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.AddFriendActivityBinding;
|
||||
|
||||
public class AddFriendActivity extends BaseAddFriendActivity {
|
||||
|
||||
@Override
|
||||
protected View initViewAndGetRootView(Bundle savedInstanceState) {
|
||||
AddFriendActivityBinding viewBinding = AddFriendActivityBinding.inflate(getLayoutInflater());
|
||||
etAddFriendAccount = viewBinding.etAddFriendAccount;
|
||||
ivAddFriendBack = viewBinding.ivAddFriendBack;
|
||||
ivFriendClear = viewBinding.ivFriendClear;
|
||||
addFriendEmptyLayout = viewBinding.addFriendEmptyLayout;
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.blacklist;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.netease.yunxin.kit.common.utils.NetworkUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.blacklist.BaseBlackListActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.BaseListActivityLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.IViewTypeConstant;
|
||||
import com.netease.yunxin.kit.contactkit.ui.normal.selector.ContactSelectorActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.normal.view.ContactViewHolderFactory;
|
||||
import com.netease.yunxin.kit.contactkit.ui.normal.view.viewholder.BlackListViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FetchCallback;
|
||||
|
||||
public class BlackListActivity extends BaseBlackListActivity {
|
||||
|
||||
@Override
|
||||
protected void configViewHolderFactory() {
|
||||
binding.contactListView.setViewHolderFactory(
|
||||
new ContactViewHolderFactory() {
|
||||
@Override
|
||||
protected BaseContactViewHolder getCustomViewHolder(ViewGroup view, int viewType) {
|
||||
if (viewType == IViewTypeConstant.CONTACT_BLACK_LIST) {
|
||||
BlackListViewHolder viewHolder = new BlackListViewHolder(view);
|
||||
viewHolder.setRelieveListener(
|
||||
data -> {
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
Toast.makeText(
|
||||
BlackListActivity.this,
|
||||
R.string.contact_network_error_tip,
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
viewModel.removeBlackOp(
|
||||
data.data.getAccount(),
|
||||
new FetchCallback<Void>() {
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
Toast.makeText(
|
||||
BlackListActivity.this,
|
||||
getText(R.string.remove_black_fail),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
Toast.makeText(
|
||||
BlackListActivity.this,
|
||||
getText(R.string.remove_black_fail),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(@Nullable Void param) {
|
||||
binding.contactListView.removeContactData(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
return viewHolder;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void configTitle(BaseListActivityLayoutBinding binding) {
|
||||
binding
|
||||
.title
|
||||
.setTitle(R.string.black_list)
|
||||
.setActionImg(R.mipmap.ic_title_bar_more)
|
||||
.setActionListener(
|
||||
v -> {
|
||||
Intent intent = new Intent(this, ContactSelectorActivity.class);
|
||||
blackListLauncher.launch(intent);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.contact;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import com.netease.yunxin.kit.contactkit.ui.contact.BaseContactActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.contact.BaseContactFragment;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.ContactActivityBinding;
|
||||
|
||||
public class ContactActivity extends BaseContactActivity {
|
||||
|
||||
@Override
|
||||
protected View initViewAndGetRootView(Bundle savedInstanceState) {
|
||||
ContactActivityBinding viewBinding = ContactActivityBinding.inflate(LayoutInflater.from(this));
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
protected BaseContactFragment getContactFragment() {
|
||||
return new ContactFragment();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.contact;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
import com.netease.yunxin.kit.contactkit.ui.normal.view.ContactViewHolderFactory;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
|
||||
public class ContactDefaultFactory extends ContactViewHolderFactory {
|
||||
@Override
|
||||
protected BaseContactViewHolder getCustomViewHolder(ViewGroup view, int viewType) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.contact;
|
||||
|
||||
import static com.netease.yunxin.kit.corekit.im.utils.RouterConstant.PATH_ADD_FRIEND_PAGE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.contact.BaseContactFragment;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.ContactFragmentBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactEntranceBean;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import com.netease.yunxin.kit.corekit.route.XKitRouter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** contact page */
|
||||
public class ContactFragment extends BaseContactFragment {
|
||||
private final String TAG = "ContactFragment";
|
||||
private ContactFragmentBinding viewBinding;
|
||||
private ContactEntranceBean verifyBean;
|
||||
|
||||
@Override
|
||||
protected View initViewAndGetRootView(
|
||||
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
viewBinding = ContactFragmentBinding.inflate(inflater, container, false);
|
||||
contactLayout = viewBinding.contactLayout;
|
||||
contactLayout
|
||||
.getContactListView()
|
||||
.getDecoration()
|
||||
.setTitleAlignBottom(false)
|
||||
.setIndexDecorationBg(getResources().getColor(R.color.color_eff1f4))
|
||||
.setColorTitleBottomLine(getResources().getColor(R.color.color_dbe0e8));
|
||||
contactLayout.getContactListView().setViewHolderFactory(new ContactDefaultFactory());
|
||||
emptyView = viewBinding.emptyLayout;
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
protected void loadTitle() {
|
||||
if (contactConfig.showTitleBar) {
|
||||
viewBinding.contactLayout.getTitleBar().setVisibility(View.VISIBLE);
|
||||
if (contactConfig.titleColor != null) {
|
||||
viewBinding.contactLayout.getTitleBar().setTitleColor(contactConfig.titleColor);
|
||||
}
|
||||
if (contactConfig.title != null) {
|
||||
viewBinding.contactLayout.getTitleBar().setTitle(contactConfig.title);
|
||||
} else {
|
||||
viewBinding
|
||||
.contactLayout
|
||||
.getTitleBar()
|
||||
.setTitle(getResources().getString(R.string.contact_title));
|
||||
}
|
||||
|
||||
} else {
|
||||
viewBinding.contactLayout.getTitleBar().setVisibility(View.GONE);
|
||||
}
|
||||
if (contactConfig.showTitleBarRight2Icon) {
|
||||
viewBinding.contactLayout.getTitleBar().showRight2ImageView(true);
|
||||
if (contactConfig.titleBarRight2Res != null) {
|
||||
viewBinding.contactLayout.getTitleBar().setRight2ImageRes(contactConfig.titleBarRight2Res);
|
||||
}
|
||||
|
||||
viewBinding
|
||||
.contactLayout
|
||||
.getTitleBar()
|
||||
.setRight2ImageClick(
|
||||
v -> {
|
||||
if (contactConfig.titleBarRight2Click != null) {
|
||||
contactConfig.titleBarRight2Click.onClick(v);
|
||||
} else {
|
||||
XKitRouter.withKey(RouterConstant.PATH_GLOBAL_SEARCH_PAGE)
|
||||
.withContext(requireContext())
|
||||
.navigate();
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
viewBinding.contactLayout.getTitleBar().showRight2ImageView(false);
|
||||
}
|
||||
|
||||
if (contactConfig.showTitleBarRightIcon) {
|
||||
viewBinding.contactLayout.getTitleBar().showRightImageView(true);
|
||||
if (contactConfig.titleBarRightRes != null) {
|
||||
viewBinding.contactLayout.getTitleBar().setRightImageRes(contactConfig.titleBarRightRes);
|
||||
}
|
||||
if (contactConfig.titleBarRightClick != null) {
|
||||
viewBinding
|
||||
.contactLayout
|
||||
.getTitleBar()
|
||||
.setRightImageClick(contactConfig.titleBarRightClick);
|
||||
} else {
|
||||
viewBinding
|
||||
.contactLayout
|
||||
.getTitleBar()
|
||||
.setRightImageClick(
|
||||
v ->
|
||||
XKitRouter.withKey(PATH_ADD_FRIEND_PAGE)
|
||||
.withContext(requireContext())
|
||||
.navigate());
|
||||
}
|
||||
|
||||
} else {
|
||||
viewBinding.contactLayout.getTitleBar().showRightImageView(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ContactEntranceBean> getContactEntranceList(Context context) {
|
||||
List<ContactEntranceBean> contactDataList = new ArrayList<>();
|
||||
//verify message
|
||||
verifyBean =
|
||||
new ContactEntranceBean(
|
||||
R.mipmap.ic_contact_verfiy_msg, context.getString(R.string.contact_list_verify_msg));
|
||||
verifyBean.router = RouterConstant.PATH_MY_NOTIFICATION_PAGE;
|
||||
//black list
|
||||
ContactEntranceBean blackBean =
|
||||
new ContactEntranceBean(
|
||||
R.mipmap.ic_contact_black_list, context.getString(R.string.contact_list_black_list));
|
||||
blackBean.router = RouterConstant.PATH_MY_BLACK_PAGE;
|
||||
//my group
|
||||
ContactEntranceBean groupBean =
|
||||
new ContactEntranceBean(
|
||||
R.mipmap.ic_contact_my_group, context.getString(R.string.contact_list_my_group));
|
||||
groupBean.router = RouterConstant.PATH_MY_TEAM_PAGE;
|
||||
|
||||
contactDataList.add(verifyBean);
|
||||
contactDataList.add(blackBean);
|
||||
contactDataList.add(groupBean);
|
||||
return contactDataList;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ContactEntranceBean configVerifyBean() {
|
||||
return verifyBean;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.search;
|
||||
|
||||
import android.view.View;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.GlobalSearchActivityBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.search.page.BaseSearchActivity;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
|
||||
/** search your friend or team */
|
||||
public class GlobalSearchActivity extends BaseSearchActivity {
|
||||
|
||||
protected View initViewAndGetRootView() {
|
||||
GlobalSearchActivityBinding viewBinding =
|
||||
GlobalSearchActivityBinding.inflate(getLayoutInflater());
|
||||
searchRv = viewBinding.rvSearch;
|
||||
clearView = viewBinding.ivClear;
|
||||
emptyView = viewBinding.emptyLl;
|
||||
searchEditText = viewBinding.etSearch;
|
||||
backView = viewBinding.globalTitleBar.getBackImageView();
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindView() {
|
||||
super.bindView();
|
||||
searchAdapter.setViewHolderFactory(new SearchViewHolderFactory());
|
||||
routerFriend = RouterConstant.PATH_CHAT_P2P_PAGE;
|
||||
routerTeam = RouterConstant.PATH_CHAT_TEAM_PAGE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.search;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.BaseViewHolder;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.IViewHolderFactory;
|
||||
import com.netease.yunxin.kit.contactkit.ui.ContactConstant;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.SearchTitleItemLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.SearchUserItemLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.normal.search.viewholder.FriendViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.normal.search.viewholder.TeamViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.normal.search.viewholder.TitleViewHolder;
|
||||
|
||||
/** search result list view holder factory */
|
||||
public class SearchViewHolderFactory implements IViewHolderFactory {
|
||||
|
||||
@Override
|
||||
public BaseViewHolder createViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
||||
if (viewType == ContactConstant.SearchViewType.TITLE) { //title view
|
||||
return new TitleViewHolder(
|
||||
SearchTitleItemLayoutBinding.inflate(
|
||||
LayoutInflater.from(parent.getContext()), parent, false));
|
||||
} else if (viewType == ContactConstant.SearchViewType.USER) { // friend view
|
||||
return new FriendViewHolder(
|
||||
SearchUserItemLayoutBinding.inflate(
|
||||
LayoutInflater.from(parent.getContext()), parent, false));
|
||||
} else if (viewType == ContactConstant.SearchViewType.TEAM) { //team view
|
||||
return new TeamViewHolder(
|
||||
SearchUserItemLayoutBinding.inflate(
|
||||
LayoutInflater.from(parent.getContext()), parent, false));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.search.viewholder;
|
||||
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.netease.nimlib.sdk.search.model.RecordHitInfo;
|
||||
import com.netease.yunxin.kit.chatkit.model.FriendSearchInfo;
|
||||
import com.netease.yunxin.kit.chatkit.model.HitType;
|
||||
import com.netease.yunxin.kit.common.ui.utils.AvatarColor;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.BaseViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.SearchUserItemLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.SearchFriendBean;
|
||||
|
||||
public class FriendViewHolder extends BaseViewHolder<SearchFriendBean> {
|
||||
private FriendSearchInfo friendInfo;
|
||||
private SearchUserItemLayoutBinding viewBinding;
|
||||
|
||||
public FriendViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
public FriendViewHolder(@NonNull SearchUserItemLayoutBinding viewBinding) {
|
||||
this(viewBinding.getRoot());
|
||||
this.viewBinding = viewBinding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindData(SearchFriendBean data, int position) {
|
||||
friendInfo = data.friendSearchInfo;
|
||||
if (friendInfo != null) {
|
||||
viewBinding.cavUserIcon.setData(
|
||||
friendInfo.getFriendInfo().getAvatar(),
|
||||
friendInfo.getFriendInfo().getName(),
|
||||
AvatarColor.avatarColor(friendInfo.getFriendInfo().getAccount()));
|
||||
if (friendInfo.getHitType() == HitType.Alias) {
|
||||
viewBinding.tvNickName.setText(
|
||||
getSelectSpanText(friendInfo.getFriendInfo().getAlias(), friendInfo.getHitInfo()));
|
||||
viewBinding.tvName.setVisibility(View.GONE);
|
||||
} else if (friendInfo.getHitType() == HitType.UserName) {
|
||||
|
||||
if (!TextUtils.isEmpty(friendInfo.getFriendInfo().getAlias())) {
|
||||
viewBinding.tvNickName.setText(friendInfo.getFriendInfo().getAlias());
|
||||
viewBinding.tvNickName.setVisibility(View.VISIBLE);
|
||||
viewBinding.tvName.setText(
|
||||
getSelectSpanText(
|
||||
friendInfo.getFriendInfo().getUserInfo().getName(), friendInfo.getHitInfo()));
|
||||
viewBinding.tvName.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
viewBinding.tvNickName.setText(
|
||||
getSelectSpanText(
|
||||
friendInfo.getFriendInfo().getUserInfo().getName(), friendInfo.getHitInfo()));
|
||||
viewBinding.tvNickName.setVisibility(View.VISIBLE);
|
||||
viewBinding.tvName.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
viewBinding.tvNickName.setVisibility(View.VISIBLE);
|
||||
if (!TextUtils.isEmpty(friendInfo.getFriendInfo().getAlias())) {
|
||||
viewBinding.tvNickName.setText(friendInfo.getFriendInfo().getAlias());
|
||||
viewBinding.tvName.setText(
|
||||
getSelectSpanText(friendInfo.getFriendInfo().getAccount(), friendInfo.getHitInfo()));
|
||||
viewBinding.tvName.setVisibility(View.VISIBLE);
|
||||
} else if (!TextUtils.isEmpty(friendInfo.getFriendInfo().getUserInfo().getName())) {
|
||||
viewBinding.tvNickName.setText(friendInfo.getFriendInfo().getUserInfo().getName());
|
||||
viewBinding.tvName.setText(
|
||||
getSelectSpanText(friendInfo.getFriendInfo().getAccount(), friendInfo.getHitInfo()));
|
||||
viewBinding.tvName.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
viewBinding.tvNickName.setText(
|
||||
getSelectSpanText(friendInfo.getFriendInfo().getAccount(), friendInfo.getHitInfo()));
|
||||
viewBinding.tvName.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
viewBinding.getRoot().setOnClickListener(v -> itemListener.onClick(v, data, position));
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
private SpannableString getSelectSpanText(String text, RecordHitInfo hitInfo) {
|
||||
SpannableString spannable = new SpannableString(text);
|
||||
if (hitInfo != null) {
|
||||
spannable.setSpan(
|
||||
new ForegroundColorSpan(
|
||||
viewBinding.getRoot().getContext().getResources().getColor(R.color.color_337eff)),
|
||||
hitInfo.start,
|
||||
hitInfo.end,
|
||||
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
return spannable;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.search.viewholder;
|
||||
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.netease.nimlib.sdk.search.model.RecordHitInfo;
|
||||
import com.netease.yunxin.kit.chatkit.model.TeamSearchInfo;
|
||||
import com.netease.yunxin.kit.common.ui.utils.AvatarColor;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.BaseViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.SearchUserItemLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.SearchTeamBean;
|
||||
|
||||
public class TeamViewHolder extends BaseViewHolder<SearchTeamBean> {
|
||||
|
||||
private SearchUserItemLayoutBinding viewBinding;
|
||||
private TeamSearchInfo searchInfo;
|
||||
|
||||
public TeamViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
public TeamViewHolder(@NonNull SearchUserItemLayoutBinding viewBinding) {
|
||||
this(viewBinding.getRoot());
|
||||
this.viewBinding = viewBinding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindData(SearchTeamBean data, int position) {
|
||||
if (data != null) {
|
||||
searchInfo = data.teamSearchInfo;
|
||||
viewBinding.cavUserIcon.setData(
|
||||
searchInfo.getTeam().getIcon(),
|
||||
searchInfo.getTeam().getName(),
|
||||
AvatarColor.avatarColor(searchInfo.getTeam().getId()));
|
||||
viewBinding.tvNickName.setText(
|
||||
getSelectSpanText(searchInfo.getTeam().getName(), searchInfo.getHitInfo()));
|
||||
viewBinding.tvNickName.setVisibility(View.VISIBLE);
|
||||
viewBinding.tvName.setVisibility(View.GONE);
|
||||
viewBinding.getRoot().setOnClickListener(v -> itemListener.onClick(v, data, position));
|
||||
}
|
||||
}
|
||||
|
||||
private SpannableString getSelectSpanText(String text, RecordHitInfo hitInfo) {
|
||||
SpannableString spannable = new SpannableString(text);
|
||||
if (hitInfo != null) {
|
||||
spannable.setSpan(
|
||||
new ForegroundColorSpan(
|
||||
viewBinding.getRoot().getContext().getResources().getColor(R.color.color_337eff)),
|
||||
hitInfo.start,
|
||||
hitInfo.end,
|
||||
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
return spannable;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.search.viewholder;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.BaseViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.SearchTitleItemLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.SearchTitleBean;
|
||||
|
||||
public class TitleViewHolder extends BaseViewHolder<SearchTitleBean> {
|
||||
|
||||
private SearchTitleItemLayoutBinding viewBinding;
|
||||
|
||||
public TitleViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
public TitleViewHolder(@NonNull SearchTitleItemLayoutBinding viewBinding) {
|
||||
this(viewBinding.getRoot());
|
||||
this.viewBinding = viewBinding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindData(SearchTitleBean data, int position) {
|
||||
if (TextUtils.isEmpty(data.title)) {
|
||||
viewBinding.tvTitle.setText(data.titleRes);
|
||||
} else {
|
||||
viewBinding.tvTitle.setText(data.title);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.selector;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import androidx.viewbinding.ViewBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.ContactSelectorActivityLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.normal.contact.ContactDefaultFactory;
|
||||
import com.netease.yunxin.kit.contactkit.ui.selector.BaseContactSelectorActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.selector.BaseSelectedListAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ContactSelectorActivity extends BaseContactSelectorActivity {
|
||||
|
||||
protected ContactSelectorActivityLayoutBinding binding;
|
||||
|
||||
@Override
|
||||
protected View initViewAndGetRootView(Bundle savedInstanceState) {
|
||||
binding = ContactSelectorActivityLayoutBinding.inflate(getLayoutInflater());
|
||||
contactListView = binding.contactListView;
|
||||
contactListView
|
||||
.getDecoration()
|
||||
.setTitleAlignBottom(false)
|
||||
.setIndexDecorationBg(getResources().getColor(R.color.color_eff1f4))
|
||||
.setColorTitleBottomLine(getResources().getColor(R.color.color_dbe0e8));
|
||||
contactListView.setViewHolderFactory(new ContactDefaultFactory());
|
||||
emptyGroup = binding.emptyLayout;
|
||||
rvSelected = binding.rvSelected;
|
||||
titleBar = binding.title;
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
protected BaseSelectedListAdapter<? extends ViewBinding> getSelectedListAdapter() {
|
||||
return new SelectedListAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ContactFriendBean> getFollowList() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.selector;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.netease.yunxin.kit.common.ui.utils.AvatarColor;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FriendSelectedViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.selector.BaseSelectedListAdapter;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendInfo;
|
||||
|
||||
public class SelectedListAdapter extends BaseSelectedListAdapter<FriendSelectedViewHolderBinding> {
|
||||
|
||||
@Override
|
||||
protected FriendSelectedViewHolderBinding provideViewBinding(
|
||||
@NonNull ViewGroup parent, int viewType) {
|
||||
return FriendSelectedViewHolderBinding.inflate(
|
||||
LayoutInflater.from(parent.getContext()), parent, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleBindViewHolder(
|
||||
SelectedViewHolder<FriendSelectedViewHolderBinding> holder,
|
||||
ContactFriendBean bean,
|
||||
FriendInfo friendData) {
|
||||
holder.binding.avatarView.setData(
|
||||
friendData.getAvatar(),
|
||||
friendData.getName(),
|
||||
AvatarColor.avatarColor(friendData.getAccount()));
|
||||
holder.itemView.setOnClickListener(
|
||||
v -> {
|
||||
removeFriend(bean);
|
||||
if (itemClickListener != null) {
|
||||
itemClickListener.onItemClick(bean);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.team;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.view.ViewGroup;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.IViewTypeConstant;
|
||||
import com.netease.yunxin.kit.contactkit.ui.normal.view.ContactViewHolderFactory;
|
||||
import com.netease.yunxin.kit.contactkit.ui.normal.view.viewholder.TeamListViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.team.BaseTeamListActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import com.netease.yunxin.kit.corekit.route.XKitRouter;
|
||||
|
||||
public class TeamListActivity extends BaseTeamListActivity {
|
||||
|
||||
@Override
|
||||
protected void configViewHolderFactory() {
|
||||
binding.contactListView.setViewHolderFactory(
|
||||
new ContactViewHolderFactory() {
|
||||
@Override
|
||||
protected BaseContactViewHolder getCustomViewHolder(ViewGroup view, int viewType) {
|
||||
if (viewType == IViewTypeConstant.CONTACT_TEAM_LIST) {
|
||||
TeamListViewHolder viewHolder = new TeamListViewHolder(view);
|
||||
viewHolder.setItemClickListener(
|
||||
data -> {
|
||||
if (isSelector) {
|
||||
Intent result = new Intent();
|
||||
result.putExtra(RouterConstant.KEY_TEAM_ID, data.data.getId());
|
||||
setResult(RESULT_OK, result);
|
||||
finish();
|
||||
} else {
|
||||
XKitRouter.withKey(data.router)
|
||||
.withParam(RouterConstant.CHAT_KRY, data.data)
|
||||
.withContext(TeamListActivity.this)
|
||||
.navigate();
|
||||
}
|
||||
});
|
||||
return viewHolder;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.userinfo;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.CommentActivityLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.userinfo.BaseCommentActivity;
|
||||
|
||||
public class CommentActivity extends BaseCommentActivity {
|
||||
|
||||
@Override
|
||||
protected View initViewAndGetRootView(Bundle savedInstanceState) {
|
||||
CommentActivityLayoutBinding binding =
|
||||
CommentActivityLayoutBinding.inflate(getLayoutInflater());
|
||||
titleBar = binding.title;
|
||||
titleBar.setActionTextColor(getResources().getColor(R.color.color_337eff));
|
||||
edtComment = binding.edtComment;
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
changeStatusBarColor(R.color.color_eff1f4);
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.userinfo;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.UserInfoActivityLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.userinfo.BaseUserInfoActivity;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import com.netease.yunxin.kit.corekit.route.XKitRouter;
|
||||
|
||||
public class UserInfoActivity extends BaseUserInfoActivity {
|
||||
|
||||
@Override
|
||||
protected View initViewAndGetRootView(Bundle savedInstanceState) {
|
||||
UserInfoActivityLayoutBinding binding =
|
||||
UserInfoActivityLayoutBinding.inflate(getLayoutInflater());
|
||||
contactInfoView = binding.contactUser;
|
||||
contactInfoView.configSignatureMaxLines(2);
|
||||
titleBar = binding.title;
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends Activity> getCommentActivity() {
|
||||
return CommentActivity.class;
|
||||
}
|
||||
|
||||
protected void goChat() {
|
||||
XKitRouter.withKey(RouterConstant.PATH_CHAT_P2P_PAGE)
|
||||
.withParam(RouterConstant.CHAT_ID_KRY, userInfoData.data.getAccount())
|
||||
.withContext(this)
|
||||
.navigate();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.verify;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
|
||||
import com.netease.yunxin.kit.contactkit.ui.ILoadListener;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactVerifyInfoBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.IViewTypeConstant;
|
||||
import com.netease.yunxin.kit.contactkit.ui.normal.view.ContactViewHolderFactory;
|
||||
import com.netease.yunxin.kit.contactkit.ui.normal.view.viewholder.VerifyInfoViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.verify.BaseVerifyListActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
import com.netease.yunxin.kit.corekit.im.model.SystemMessageInfoStatus;
|
||||
import com.netease.yunxin.kit.corekit.im.model.SystemMessageInfoType;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FetchCallback;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import com.netease.yunxin.kit.corekit.route.XKitRouter;
|
||||
|
||||
public class VerifyListActivity extends BaseVerifyListActivity implements ILoadListener {
|
||||
@Override
|
||||
protected void initView() {
|
||||
super.initView();
|
||||
binding.title.setBackgroundColor(getResources().getColor(R.color.color_white));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configViewHolderFactory() {
|
||||
binding.contactListView.setViewHolderFactory(
|
||||
new ContactViewHolderFactory() {
|
||||
@Override
|
||||
protected BaseContactViewHolder getCustomViewHolder(ViewGroup view, int viewType) {
|
||||
if (viewType == IViewTypeConstant.CONTACT_VERIFY_INFO) {
|
||||
VerifyInfoViewHolder viewHolder = new VerifyInfoViewHolder(view);
|
||||
viewHolder.setVerifyListener(
|
||||
new VerifyInfoViewHolder.VerifyListener() {
|
||||
@Override
|
||||
public void onAccept(ContactVerifyInfoBean bean) {
|
||||
viewModel.agree(
|
||||
bean,
|
||||
new FetchCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable Void param) {
|
||||
viewModel.setVerifyStatus(bean, SystemMessageInfoStatus.Passed);
|
||||
binding.contactListView.updateContactData(bean);
|
||||
if (bean.data.getInfoType() == SystemMessageInfoType.AddFriend) {
|
||||
XKitRouter.withKey(RouterConstant.PATH_CHAT_SEND_TEXT_ACTION)
|
||||
.withContext(VerifyListActivity.this)
|
||||
.withParam(
|
||||
RouterConstant.KEY_SESSION_ID, bean.data.getFromAccount())
|
||||
.withParam(
|
||||
RouterConstant.KEY_SESSION_TYPE,
|
||||
SessionTypeEnum.P2P.getValue())
|
||||
.withParam(
|
||||
RouterConstant.KEY_MESSAGE_CONTENT,
|
||||
getResources()
|
||||
.getString(R.string.verify_agree_message_text))
|
||||
.navigate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
if (code == error_duplicate) {
|
||||
viewModel.setVerifyStatus(bean, SystemMessageInfoStatus.Passed);
|
||||
binding.contactListView.updateContactData(bean);
|
||||
}
|
||||
toastResult(true, bean.data.getInfoType(), code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
toastResult(true, bean.data.getInfoType(), 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReject(ContactVerifyInfoBean bean) {
|
||||
viewModel.disagree(
|
||||
bean,
|
||||
new FetchCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable Void param) {
|
||||
viewModel.setVerifyStatus(bean, SystemMessageInfoStatus.Declined);
|
||||
binding.contactListView.updateContactData(bean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
if (code == error_duplicate) {
|
||||
viewModel.setVerifyStatus(bean, SystemMessageInfoStatus.Passed);
|
||||
binding.contactListView.updateContactData(bean);
|
||||
}
|
||||
toastResult(false, bean.data.getInfoType(), code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
toastResult(false, bean.data.getInfoType(), 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return viewHolder;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected int getEmptyStateViewRes() {
|
||||
return R.drawable.ic_contact_empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.view;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
import com.netease.yunxin.kit.contactkit.ui.IContactFactory;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.IViewTypeConstant;
|
||||
import com.netease.yunxin.kit.contactkit.ui.normal.view.viewholder.ContactViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.normal.view.viewholder.EntranceViewHolder;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
|
||||
/** viewHolder factory */
|
||||
public abstract class ContactViewHolderFactory implements IContactFactory {
|
||||
|
||||
@Override
|
||||
public int getItemViewType(BaseContactBean data) {
|
||||
return data.viewType;
|
||||
}
|
||||
|
||||
public BaseContactViewHolder createViewHolder(ViewGroup view, int viewType) {
|
||||
if (viewType == IViewTypeConstant.CONTACT_FRIEND) {
|
||||
return new ContactViewHolder(view);
|
||||
} else if (viewType == IViewTypeConstant.CONTACT_ACTION_ENTER) {
|
||||
return new EntranceViewHolder(view);
|
||||
} else if (viewType >= IViewTypeConstant.CUSTOM_START) {
|
||||
return getCustomViewHolder(view, viewType);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected abstract BaseContactViewHolder getCustomViewHolder(ViewGroup view, int viewType);
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.view.viewholder;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.BlackListViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactBlackListBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.utils.ColorUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListViewAttrs;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
import com.netease.yunxin.kit.corekit.im.model.UserInfo;
|
||||
|
||||
public class BlackListViewHolder extends BaseContactViewHolder {
|
||||
|
||||
private RelieveListener relieveListener;
|
||||
|
||||
private BlackListViewHolderBinding binding;
|
||||
|
||||
public BlackListViewHolder(@NonNull ViewGroup itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initViewBinding(LayoutInflater layoutInflater, ViewGroup container) {
|
||||
binding = BlackListViewHolderBinding.inflate(layoutInflater, container, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(BaseContactBean bean, int position, ContactListViewAttrs attrs) {
|
||||
ContactBlackListBean blackListBean = ((ContactBlackListBean) bean);
|
||||
UserInfo friendData = ((ContactBlackListBean) bean).data;
|
||||
binding.tvName.setText(blackListBean.getName());
|
||||
|
||||
binding.avatarView.setData(
|
||||
friendData.getAvatar(),
|
||||
blackListBean.getAvatarName(),
|
||||
ColorUtils.avatarColor(friendData.getAccount()));
|
||||
|
||||
binding.tvRelieve.setOnClickListener(
|
||||
v -> {
|
||||
if (relieveListener != null) {
|
||||
relieveListener.onUserRelieve((ContactBlackListBean) bean);
|
||||
}
|
||||
});
|
||||
loadConfig(attrs);
|
||||
}
|
||||
|
||||
private void loadConfig(ContactListViewAttrs attrs) {
|
||||
if (attrs == null) {
|
||||
return;
|
||||
}
|
||||
if (attrs.getNameTextColor() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvName.setTextColor(attrs.getNameTextColor());
|
||||
}
|
||||
if (attrs.getNameTextSize() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvName.setTextSize(attrs.getNameTextSize());
|
||||
}
|
||||
|
||||
if (attrs.getAvatarCornerRadius() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.avatarView.setCornerRadius(attrs.getAvatarCornerRadius());
|
||||
}
|
||||
}
|
||||
|
||||
public void setRelieveListener(RelieveListener relieveListener) {
|
||||
this.relieveListener = relieveListener;
|
||||
}
|
||||
|
||||
public interface RelieveListener {
|
||||
void onUserRelieve(ContactBlackListBean data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.view.viewholder;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.FriendContactViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.utils.ColorUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListViewAttrs;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendInfo;
|
||||
|
||||
public class ContactViewHolder extends BaseContactViewHolder {
|
||||
|
||||
FriendContactViewHolderBinding binding;
|
||||
|
||||
public ContactViewHolder(@NonNull ViewGroup itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initViewBinding(LayoutInflater layoutInflater, ViewGroup container) {
|
||||
binding = FriendContactViewHolderBinding.inflate(layoutInflater, container, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(BaseContactBean bean, int position, ContactListViewAttrs attrs) {
|
||||
FriendInfo friendInfo = ((ContactFriendBean) bean).data;
|
||||
String nickName = friendInfo.getName();
|
||||
String avatarName = friendInfo.getAvatarName();
|
||||
binding.tvName.setText(nickName);
|
||||
|
||||
binding.avatarView.setData(
|
||||
friendInfo.getAvatar(), avatarName, ColorUtils.avatarColor(friendInfo.getAccount()));
|
||||
|
||||
if (attrs.getShowSelector()) {
|
||||
binding.rbSelector.setChecked(((ContactFriendBean) bean).isSelected());
|
||||
binding.rbSelector.setVisibility(View.VISIBLE);
|
||||
binding.rootView.setOnClickListener(
|
||||
v -> {
|
||||
boolean newStatue = !binding.rbSelector.isChecked();
|
||||
((ContactFriendBean) bean).setSelected(newStatue);
|
||||
binding.rbSelector.setChecked(newStatue);
|
||||
if (actions != null && actions.getSelectorListener(bean.viewType) != null) {
|
||||
actions.getSelectorListener(bean.viewType).onSelector(newStatue, bean);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
binding.rbSelector.setVisibility(View.GONE);
|
||||
binding.rootView.setOnClickListener(
|
||||
v -> {
|
||||
if (actions != null && actions.getContactListener(bean.viewType) != null) {
|
||||
actions.getContactListener(bean.viewType).onClick(position, bean);
|
||||
}
|
||||
});
|
||||
}
|
||||
loadConfig(attrs);
|
||||
}
|
||||
|
||||
private void loadConfig(ContactListViewAttrs attrs) {
|
||||
if (attrs == null) {
|
||||
return;
|
||||
}
|
||||
if (attrs.getNameTextColor() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvName.setTextColor(attrs.getNameTextColor());
|
||||
}
|
||||
if (attrs.getNameTextSize() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvName.setTextSize(attrs.getNameTextSize());
|
||||
}
|
||||
|
||||
if (attrs.getAvatarCornerRadius() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.avatarView.setCornerRadius(attrs.getAvatarCornerRadius());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.view.viewholder;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.EntranceContactViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactEntranceBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListViewAttrs;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
|
||||
public class EntranceViewHolder extends BaseContactViewHolder {
|
||||
|
||||
EntranceContactViewHolderBinding binding;
|
||||
private static final int maxNumber = 99;
|
||||
|
||||
public EntranceViewHolder(@NonNull ViewGroup itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initViewBinding(LayoutInflater layoutInflater, ViewGroup container) {
|
||||
binding = EntranceContactViewHolderBinding.inflate(layoutInflater, container, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(BaseContactBean bean, int position, ContactListViewAttrs attrs) {
|
||||
ContactEntranceBean entranceBean = (ContactEntranceBean) bean;
|
||||
if (entranceBean.showRightArrow) {
|
||||
binding.ivArrow.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
binding.ivArrow.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (entranceBean.number > 0) {
|
||||
binding.tvNumber.setVisibility(View.VISIBLE);
|
||||
String numberValue = String.valueOf(entranceBean.number);
|
||||
if (entranceBean.number > maxNumber) {
|
||||
numberValue = context.getResources().getString(R.string.verify_max_count_text);
|
||||
}
|
||||
binding.tvNumber.setText(numberValue);
|
||||
} else {
|
||||
binding.tvNumber.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
Glide.with(context).load(entranceBean.icon).centerCrop().into(binding.ivIcon);
|
||||
|
||||
binding.tvTitle.setText(entranceBean.title);
|
||||
|
||||
binding.rootView.setOnClickListener(
|
||||
v -> {
|
||||
if (actions != null && actions.getContactListener(bean.viewType) != null) {
|
||||
actions.getContactListener(bean.viewType).onClick(position, bean);
|
||||
}
|
||||
});
|
||||
|
||||
loadConfig(attrs);
|
||||
}
|
||||
|
||||
private void loadConfig(ContactListViewAttrs attrs) {
|
||||
if (attrs == null) {
|
||||
return;
|
||||
}
|
||||
if (attrs.getNameTextColor() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvTitle.setTextColor(attrs.getNameTextColor());
|
||||
}
|
||||
if (attrs.getNameTextSize() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvTitle.setTextSize(attrs.getNameTextSize());
|
||||
}
|
||||
|
||||
if (attrs.getAvatarCornerRadius() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.flIvIcon.setRadius(attrs.getAvatarCornerRadius());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.view.viewholder;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.netease.nimlib.sdk.team.model.Team;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.TeamListViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactTeamBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.utils.ColorUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListViewAttrs;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
|
||||
public class TeamListViewHolder extends BaseContactViewHolder {
|
||||
|
||||
private itemClickListener itemClickListener;
|
||||
|
||||
private TeamListViewHolderBinding binding;
|
||||
|
||||
public TeamListViewHolder(@NonNull ViewGroup itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initViewBinding(LayoutInflater layoutInflater, ViewGroup container) {
|
||||
binding = TeamListViewHolderBinding.inflate(layoutInflater, container, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(BaseContactBean bean, int position, ContactListViewAttrs attrs) {
|
||||
Team teamInfo = ((ContactTeamBean) bean).data;
|
||||
binding.tvName.setText(teamInfo.getName());
|
||||
|
||||
binding.avatarView.setData(
|
||||
teamInfo.getIcon(), teamInfo.getName(), ColorUtils.avatarColor(teamInfo.getId()));
|
||||
|
||||
binding.rootView.setOnClickListener(
|
||||
v -> {
|
||||
if (itemClickListener != null) {
|
||||
itemClickListener.onClick((ContactTeamBean) bean);
|
||||
}
|
||||
});
|
||||
|
||||
loadConfig(attrs);
|
||||
}
|
||||
|
||||
private void loadConfig(ContactListViewAttrs attrs) {
|
||||
if (attrs == null) {
|
||||
return;
|
||||
}
|
||||
if (attrs.getNameTextColor() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvName.setTextColor(attrs.getNameTextColor());
|
||||
}
|
||||
if (attrs.getNameTextSize() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvName.setTextSize(attrs.getNameTextSize());
|
||||
}
|
||||
|
||||
if (attrs.getAvatarCornerRadius() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.avatarView.setCornerRadius(attrs.getAvatarCornerRadius());
|
||||
}
|
||||
}
|
||||
|
||||
public void setItemClickListener(TeamListViewHolder.itemClickListener itemClickListener) {
|
||||
this.itemClickListener = itemClickListener;
|
||||
}
|
||||
|
||||
public interface itemClickListener {
|
||||
void onClick(ContactTeamBean data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.normal.view.viewholder;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.netease.yunxin.kit.common.ui.utils.AvatarColor;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.VerifyListViewHolderBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactVerifyInfoBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListViewAttrs;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendNotify;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendVerifyType;
|
||||
import com.netease.yunxin.kit.corekit.im.model.SystemMessageInfo;
|
||||
|
||||
public class VerifyInfoViewHolder extends BaseContactViewHolder {
|
||||
|
||||
private VerifyListener verifyListener;
|
||||
|
||||
private VerifyListViewHolderBinding binding;
|
||||
|
||||
public VerifyInfoViewHolder(@NonNull ViewGroup itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initViewBinding(LayoutInflater layoutInflater, ViewGroup container) {
|
||||
binding = VerifyListViewHolderBinding.inflate(layoutInflater, container, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(BaseContactBean bean, int position, ContactListViewAttrs attrs) {
|
||||
ContactVerifyInfoBean infoBean = ((ContactVerifyInfoBean) bean);
|
||||
SystemMessageInfo info = infoBean.data;
|
||||
String name = info.getFromUserName();
|
||||
String targetName = info.getTargetName();
|
||||
String avatar =
|
||||
info.getTargetTeam() != null
|
||||
? info.getTargetTeam().getIcon()
|
||||
: info.getFromUserInfo().getAvatar();
|
||||
binding.tvName.setText(name);
|
||||
|
||||
binding.avatarView.setData(avatar, name, AvatarColor.avatarColor(info.getFromAccount()));
|
||||
int unreadCount = infoBean.getUnreadCount();
|
||||
if (unreadCount > 1) {
|
||||
binding.unreadTv.setVisibility(View.VISIBLE);
|
||||
if (unreadCount > 99) {
|
||||
binding.unreadTv.setText(context.getString(R.string.verify_max_count_text));
|
||||
} else {
|
||||
binding.unreadTv.setText(String.valueOf(unreadCount));
|
||||
}
|
||||
} else {
|
||||
binding.unreadTv.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (infoBean.data.getUnread()) {
|
||||
binding.rootView.setBackgroundColor(context.getResources().getColor(R.color.color_ededef));
|
||||
} else {
|
||||
binding.rootView.setBackgroundColor(context.getResources().getColor(R.color.color_white));
|
||||
}
|
||||
|
||||
switch (info.getInfoStatus()) {
|
||||
case Init:
|
||||
binding.llyVerifyResult.setVisibility(View.GONE);
|
||||
binding.llyVerify.setVisibility(View.VISIBLE);
|
||||
binding.tvAccept.setOnClickListener(
|
||||
v -> {
|
||||
if (verifyListener != null) {
|
||||
verifyListener.onAccept((ContactVerifyInfoBean) bean);
|
||||
}
|
||||
});
|
||||
binding.tvReject.setOnClickListener(
|
||||
v -> {
|
||||
if (verifyListener != null) {
|
||||
verifyListener.onReject((ContactVerifyInfoBean) bean);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case Passed:
|
||||
showResult(context.getString(R.string.contact_verify_agreed), true);
|
||||
break;
|
||||
case Declined:
|
||||
showResult(context.getString(R.string.contact_verify_rejected), false);
|
||||
break;
|
||||
case Ignored:
|
||||
case Expired:
|
||||
showResult(context.getString(R.string.contact_verify_expired), false);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (info.getInfoType()) {
|
||||
case ApplyJoinTeam:
|
||||
binding.tvAction.setText(
|
||||
String.format(context.getString(R.string.apply_to_join_group), targetName));
|
||||
break;
|
||||
case RejectTeamApply:
|
||||
binding.tvAction.setText(
|
||||
String.format(context.getString(R.string.apply_to_join_group), targetName));
|
||||
showResult(context.getString(R.string.contact_verify_agreed), false);
|
||||
break;
|
||||
case TeamInvite:
|
||||
binding.tvAction.setText(
|
||||
String.format(context.getString(R.string.invited_to_join_group), targetName));
|
||||
break;
|
||||
case DeclineTeamInvite:
|
||||
binding.tvAction.setText(
|
||||
String.format(context.getString(R.string.invited_to_join_group), targetName));
|
||||
showResult(context.getString(R.string.contact_verify_agreed), false);
|
||||
break;
|
||||
case AddFriend:
|
||||
if (info.getAttachObject() != null && info.getAttachObject() instanceof FriendNotify) {
|
||||
FriendNotify notifyAttach = (FriendNotify) info.getAttachObject();
|
||||
if (notifyAttach.getType() == FriendVerifyType.AgreeAdd) {
|
||||
binding.tvAction.setText(R.string.accept_your_friend_apply);
|
||||
showResult(null, true);
|
||||
} else if (notifyAttach.getType() == FriendVerifyType.DirectAdd) {
|
||||
binding.tvAction.setText(R.string.direct_add_your_friend_apply);
|
||||
showResult(null, true);
|
||||
} else if (notifyAttach.getType() == FriendVerifyType.RejectAdd) {
|
||||
binding.tvAction.setText(R.string.reject_your_friend_apply);
|
||||
showResult(null, true);
|
||||
} else if (notifyAttach.getType() == FriendVerifyType.VerifyRequest) {
|
||||
binding.tvAction.setText(R.string.friend_apply);
|
||||
}
|
||||
} else {
|
||||
binding.tvAction.setText(R.string.friend_apply);
|
||||
}
|
||||
break;
|
||||
case Undefined:
|
||||
break;
|
||||
}
|
||||
|
||||
loadConfig(attrs);
|
||||
}
|
||||
|
||||
private void loadConfig(ContactListViewAttrs attrs) {
|
||||
if (attrs == null) {
|
||||
return;
|
||||
}
|
||||
if (attrs.getNameTextColor() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvName.setTextColor(attrs.getNameTextColor());
|
||||
}
|
||||
if (attrs.getNameTextSize() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.tvName.setTextSize(attrs.getNameTextSize());
|
||||
}
|
||||
|
||||
if (attrs.getAvatarCornerRadius() != ContactListViewAttrs.INT_NULL) {
|
||||
binding.avatarView.setCornerRadius(attrs.getAvatarCornerRadius());
|
||||
}
|
||||
}
|
||||
|
||||
private void showResult(String content, boolean agreeIcon) {
|
||||
if (!TextUtils.isEmpty(content)) {
|
||||
binding.tvVerifyResult.setText(content);
|
||||
binding.ivVerifyResult.setImageResource(
|
||||
agreeIcon ? R.mipmap.ic_agree_status : R.mipmap.ic_reject_status);
|
||||
binding.llyVerifyResult.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
binding.llyVerifyResult.setVisibility(View.GONE);
|
||||
}
|
||||
binding.llyVerify.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
public void setVerifyListener(VerifyListener verifyListener) {
|
||||
this.verifyListener = verifyListener;
|
||||
}
|
||||
|
||||
public interface VerifyListener {
|
||||
void onAccept(ContactVerifyInfoBean bean);
|
||||
|
||||
void onReject(ContactVerifyInfoBean bean);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.search;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.BaseBean;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.BaseViewHolder;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.IViewHolderFactory;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.ViewHolderClickListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SearchAdapter extends RecyclerView.Adapter<BaseViewHolder> {
|
||||
|
||||
private final String TAG = "SearchAdapter";
|
||||
private IViewHolderFactory viewHolderFactory;
|
||||
private final List<BaseBean> dataList = new ArrayList<>();
|
||||
private ViewHolderClickListener clickListener;
|
||||
|
||||
public void setData(List<BaseBean> data) {
|
||||
dataList.clear();
|
||||
if (data != null) {
|
||||
dataList.addAll(data);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void addForwardData(List<BaseBean> data) {
|
||||
if (data != null) {
|
||||
dataList.addAll(0, data);
|
||||
}
|
||||
}
|
||||
|
||||
public void appendData(List<BaseBean> data) {
|
||||
if (data != null) {
|
||||
dataList.addAll(data);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeData(BaseBean data) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
int index = -1;
|
||||
for (int j = 0; j < dataList.size(); j++) {
|
||||
if (data.equals(dataList.get(j))) {
|
||||
index = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index > -1) {
|
||||
removeData(index);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeData(int position) {
|
||||
if (position >= 0 && position < dataList.size()) {
|
||||
dataList.remove(position);
|
||||
notifyItemRemoved(position);
|
||||
}
|
||||
}
|
||||
|
||||
public void setViewHolderFactory(IViewHolderFactory factory) {
|
||||
this.viewHolderFactory = factory;
|
||||
}
|
||||
|
||||
public void setViewHolderClickListener(ViewHolderClickListener listener) {
|
||||
this.clickListener = listener;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
BaseViewHolder viewHolder = null;
|
||||
if (viewHolderFactory != null) {
|
||||
viewHolder = viewHolderFactory.createViewHolder(parent, viewType);
|
||||
}
|
||||
return viewHolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull BaseViewHolder holder, int position) {
|
||||
holder.onBindData(dataList.get(position), position);
|
||||
holder.setItemOnClickListener(clickListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return dataList.get(position).viewType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return dataList.size();
|
||||
}
|
||||
|
||||
public BaseBean getData(int index) {
|
||||
if (index >= 0 && index < dataList.size()) {
|
||||
return dataList.get(index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.search;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.netease.yunxin.kit.alog.ALog;
|
||||
import com.netease.yunxin.kit.chatkit.model.FriendSearchInfo;
|
||||
import com.netease.yunxin.kit.chatkit.model.TeamSearchInfo;
|
||||
import com.netease.yunxin.kit.chatkit.repo.SearchRepo;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.BaseBean;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.BaseViewModel;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.FetchResult;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.LoadStatus;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.SearchFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.SearchTeamBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.SearchTitleBean;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FetchCallback;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* to provider search data and operation
|
||||
*/
|
||||
public class SearchViewModel extends BaseViewModel {
|
||||
|
||||
private static final String TAG = "SearchViewModel";
|
||||
private static final String LIB_TAG = "SearchKit-UI";
|
||||
private final MutableLiveData<FetchResult<List<BaseBean>>> queryLiveData =
|
||||
new MutableLiveData<>();
|
||||
|
||||
private final List<BaseBean> resultList = new ArrayList<>();
|
||||
|
||||
public MutableLiveData<FetchResult<List<BaseBean>>> getQueryLiveData() {
|
||||
return queryLiveData;
|
||||
}
|
||||
|
||||
protected String routerFriend;
|
||||
protected String routerTeam;
|
||||
|
||||
public void setRouter(String friend, String team) {
|
||||
routerFriend = friend;
|
||||
routerTeam = team;
|
||||
}
|
||||
|
||||
public void query(String text) {
|
||||
|
||||
resultList.clear();
|
||||
if (!TextUtils.isEmpty(text)) {
|
||||
SearchRepo.searchFriend(
|
||||
text,
|
||||
new FetchCallback<List<FriendSearchInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable List<FriendSearchInfo> param) {
|
||||
if (param != null && param.size() > 0) {
|
||||
List<BaseBean> friendResult = new ArrayList<>();
|
||||
friendResult.add(new SearchTitleBean(R.string.global_search_friend_title));
|
||||
ALog.d(LIB_TAG, TAG, "searchFriend,onSuccess,friend");
|
||||
for (int index = 0; index < param.size(); index++) {
|
||||
friendResult.add(new SearchFriendBean(param.get(index), routerFriend));
|
||||
ALog.d(
|
||||
LIB_TAG,
|
||||
TAG,
|
||||
"searchFriend,onSuccess:" + param.get(index).getFriendInfo().getName());
|
||||
}
|
||||
resultList.addAll(0, friendResult);
|
||||
}
|
||||
FetchResult<List<BaseBean>> fetchResult = new FetchResult<>(LoadStatus.Success);
|
||||
fetchResult.setData(resultList);
|
||||
queryLiveData.postValue(fetchResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "searchFriend,onFailed:" + code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "searchFriend,onException");
|
||||
}
|
||||
});
|
||||
|
||||
SearchRepo.searchGroup(
|
||||
text,
|
||||
new FetchCallback<List<TeamSearchInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable List<TeamSearchInfo> param) {
|
||||
if (param != null && param.size() > 0) {
|
||||
List<BaseBean> groupResult = new ArrayList<>();
|
||||
groupResult.add(new SearchTitleBean(R.string.global_search_group_title));
|
||||
for (int index = 0; index < param.size(); index++) {
|
||||
groupResult.add(new SearchTeamBean(param.get(index), routerTeam));
|
||||
}
|
||||
ALog.d(LIB_TAG, TAG, "searchTeamm,onSuccess,team:" + param.size());
|
||||
resultList.addAll(groupResult);
|
||||
}
|
||||
FetchResult<List<BaseBean>> fetchResult = new FetchResult<>(LoadStatus.Success);
|
||||
fetchResult.setData(resultList);
|
||||
queryLiveData.postValue(fetchResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "searchFriend,onFailed:" + code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "searchFriend:onException");
|
||||
}
|
||||
});
|
||||
|
||||
SearchRepo.searchTeam(
|
||||
text,
|
||||
new FetchCallback<List<TeamSearchInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable List<TeamSearchInfo> param) {
|
||||
if (param != null && param.size() > 0) {
|
||||
List<BaseBean> friendResult = new ArrayList<>();
|
||||
friendResult.add(new SearchTitleBean(R.string.global_search_team_title));
|
||||
for (int index = 0; index < param.size(); index++) {
|
||||
friendResult.add(new SearchTeamBean(param.get(index), routerTeam));
|
||||
}
|
||||
resultList.addAll(friendResult);
|
||||
ALog.d(LIB_TAG, TAG, "searchTeam,onSuccess:" + friendResult.size());
|
||||
}
|
||||
FetchResult<List<BaseBean>> fetchResult = new FetchResult<>(LoadStatus.Success);
|
||||
fetchResult.setData(resultList);
|
||||
queryLiveData.postValue(fetchResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "searchFriend,onFailed:" + code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "searchFriend,onException");
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
FetchResult<List<BaseBean>> fetchResult = new FetchResult<>(LoadStatus.Success);
|
||||
fetchResult.setData(resultList);
|
||||
queryLiveData.postValue(fetchResult);
|
||||
}
|
||||
}
|
||||
|
||||
public void queryFriend(String text) {
|
||||
resultList.clear();
|
||||
if (!TextUtils.isEmpty(text)) {
|
||||
SearchRepo.searchFriend(
|
||||
text,
|
||||
new FetchCallback<List<FriendSearchInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable List<FriendSearchInfo> param) {
|
||||
if (param != null && param.size() > 0) {
|
||||
List<BaseBean> friendResult = new ArrayList<>();
|
||||
friendResult.add(new SearchTitleBean(R.string.global_search_friend_title));
|
||||
ALog.d(LIB_TAG, TAG, "searchFriend,onSuccess,friend");
|
||||
for (int index = 0; index < param.size(); index++) {
|
||||
friendResult.add(new SearchFriendBean(param.get(index), routerFriend));
|
||||
ALog.d(
|
||||
LIB_TAG,
|
||||
TAG,
|
||||
"searchFriend,onSuccess:" + param.get(index).getFriendInfo().getName());
|
||||
}
|
||||
resultList.addAll(0, friendResult);
|
||||
}
|
||||
FetchResult<List<BaseBean>> fetchResult = new FetchResult<>(LoadStatus.Success);
|
||||
fetchResult.setData(resultList);
|
||||
queryLiveData.postValue(fetchResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "searchFriend,onFailed:" + code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "searchFriend,onException");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
FetchResult<List<BaseBean>> fetchResult = new FetchResult<>(LoadStatus.Success);
|
||||
fetchResult.setData(resultList);
|
||||
queryLiveData.postValue(fetchResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.search.page;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.netease.yunxin.kit.common.ui.activities.BaseActivity;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.BaseBean;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.ViewHolderClickListener;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.LoadStatus;
|
||||
import com.netease.yunxin.kit.common.utils.KeyboardUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.search.SearchAdapter;
|
||||
import com.netease.yunxin.kit.contactkit.ui.search.SearchViewModel;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import com.netease.yunxin.kit.corekit.route.XKitRouter;
|
||||
import java.util.Objects;
|
||||
|
||||
/** search your friend or team */
|
||||
public abstract class BaseSearchActivity extends BaseActivity {
|
||||
protected RecyclerView searchRv;
|
||||
|
||||
private View rootView;
|
||||
|
||||
protected View clearView;
|
||||
|
||||
protected EditText searchEditText;
|
||||
|
||||
protected View emptyView;
|
||||
|
||||
protected View backView;
|
||||
|
||||
protected SearchViewModel viewModel;
|
||||
protected SearchAdapter searchAdapter;
|
||||
protected Handler searchHandler;
|
||||
|
||||
protected String routerFriend = RouterConstant.PATH_CHAT_P2P_PAGE;
|
||||
protected String routerTeam = RouterConstant.PATH_CHAT_TEAM_PAGE;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
rootView = initViewAndGetRootView();
|
||||
checkViews();
|
||||
setContentView(rootView);
|
||||
bindView();
|
||||
initData();
|
||||
showKeyBoard();
|
||||
}
|
||||
|
||||
protected abstract View initViewAndGetRootView();
|
||||
|
||||
protected void checkViews() {
|
||||
Objects.requireNonNull(rootView);
|
||||
Objects.requireNonNull(clearView);
|
||||
Objects.requireNonNull(searchEditText);
|
||||
Objects.requireNonNull(emptyView);
|
||||
Objects.requireNonNull(backView);
|
||||
}
|
||||
|
||||
protected void bindView() {
|
||||
if (searchRv != null) {
|
||||
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
|
||||
searchRv.setLayoutManager(layoutManager);
|
||||
searchAdapter = new SearchAdapter();
|
||||
searchAdapter.setViewHolderClickListener(
|
||||
new ViewHolderClickListener() {
|
||||
@Override
|
||||
public boolean onClick(View v, BaseBean data, int position) {
|
||||
if (!TextUtils.isEmpty(data.router)) {
|
||||
XKitRouter.withKey(data.router)
|
||||
.withParam(data.paramKey, data.param)
|
||||
.withContext(BaseSearchActivity.this)
|
||||
.navigate();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View v, BaseBean data, int position) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
searchRv.setAdapter(searchAdapter);
|
||||
}
|
||||
|
||||
if (clearView != null && searchEditText != null) {
|
||||
clearView.setOnClickListener(v -> searchEditText.setText(""));
|
||||
}
|
||||
|
||||
if (searchEditText != null) {
|
||||
searchEditText.addTextChangedListener(
|
||||
new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
searchHandler.removeCallbacksAndMessages(null);
|
||||
searchHandler.postDelayed(() -> viewModel.query(String.valueOf(s)), 500);
|
||||
if (clearView != null) {
|
||||
if (TextUtils.isEmpty(String.valueOf(s))) {
|
||||
clearView.setVisibility(View.GONE);
|
||||
} else {
|
||||
clearView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
searchEditText.setOnEditorActionListener(
|
||||
(v, actionId, event) -> event.getKeyCode() == KeyEvent.KEYCODE_ENTER);
|
||||
}
|
||||
if (backView != null) {
|
||||
backView.setOnClickListener(v -> onBackPressed());
|
||||
}
|
||||
}
|
||||
|
||||
private void initData() {
|
||||
searchHandler = new Handler();
|
||||
viewModel = new ViewModelProvider(this).get(SearchViewModel.class);
|
||||
viewModel.setRouter(routerFriend, routerTeam);
|
||||
viewModel
|
||||
.getQueryLiveData()
|
||||
.observe(
|
||||
this,
|
||||
result -> {
|
||||
if (result.getLoadStatus() == LoadStatus.Success) {
|
||||
showEmpty(
|
||||
(result.getData() == null || result.getData().size() < 1)
|
||||
&& !TextUtils.isEmpty(String.valueOf(searchEditText.getEditableText())));
|
||||
searchAdapter.setData(result.getData());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showKeyBoard() {
|
||||
searchHandler.postDelayed(
|
||||
() -> {
|
||||
if (searchEditText != null) {
|
||||
searchEditText.requestFocus();
|
||||
KeyboardUtils.showKeyboard(searchEditText);
|
||||
}
|
||||
},
|
||||
300);
|
||||
}
|
||||
|
||||
private void showEmpty(boolean show) {
|
||||
if (emptyView != null) {
|
||||
emptyView.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||
if (searchRv != null) {
|
||||
searchRv.setVisibility(show ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (searchHandler != null) {
|
||||
searchHandler.removeCallbacksAndMessages(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,526 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.selector;
|
||||
|
||||
import static com.netease.yunxin.kit.corekit.im.utils.RouterConstant.KEY_REQUEST_SELECTOR_NAME;
|
||||
import static com.netease.yunxin.kit.corekit.im.utils.RouterConstant.REQUEST_CONTACT_SELECTOR_KEY;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.viewbinding.ViewBinding;
|
||||
|
||||
import com.netease.nimlib.sdk.NIMClient;
|
||||
import com.netease.nimlib.sdk.msg.MsgService;
|
||||
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
|
||||
import com.netease.nimlib.sdk.msg.model.RecentContact;
|
||||
import com.netease.yunxin.kit.chatkit.model.ConversationInfo;
|
||||
import com.netease.yunxin.kit.chatkit.repo.ContactRepo;
|
||||
import com.netease.yunxin.kit.common.ui.activities.BaseActivity;
|
||||
import com.netease.yunxin.kit.common.ui.utils.ToastUtils;
|
||||
import com.netease.yunxin.kit.common.ui.viewholder.BaseBean;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.LoadStatus;
|
||||
import com.netease.yunxin.kit.common.ui.widgets.BackTitleBar;
|
||||
import com.netease.yunxin.kit.common.utils.NetworkUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.contact.ContactViewModel;
|
||||
import com.netease.yunxin.kit.contactkit.ui.interfaces.ContactActions;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.IViewTypeConstant;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.SearchFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.search.SearchViewModel;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListView;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import com.netease.yunxin.kit.corekit.route.XKitRouter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class BaseContactSelectorActivity extends BaseActivity {
|
||||
|
||||
public static final int DEFAULT_MAX_SELECT_COUNT = 500;
|
||||
|
||||
private View rootView;
|
||||
|
||||
protected BackTitleBar titleBar;
|
||||
|
||||
protected RecyclerView rvSelected;
|
||||
|
||||
protected EditText editSearch;
|
||||
protected View ivClean;
|
||||
|
||||
protected ViewGroup emptyGroup;
|
||||
|
||||
protected ContactListView contactListView;
|
||||
|
||||
protected ContactViewModel viewModel;
|
||||
|
||||
protected SearchViewModel searchViewModel;
|
||||
|
||||
protected BaseSelectedListAdapter<?> selectedListAdapter;
|
||||
|
||||
protected ArrayList<String> filterUser;
|
||||
|
||||
protected int maxSelectCount = DEFAULT_MAX_SELECT_COUNT;
|
||||
|
||||
protected boolean selectFinalCheckCountEnable = false;
|
||||
|
||||
protected boolean checkNetworkEnable = true;
|
||||
|
||||
protected boolean enableReturnName;
|
||||
protected ContactListView loveContactView;
|
||||
protected ContactListView lastContactView;
|
||||
protected ContactListView searchContactView;
|
||||
|
||||
protected LinearLayout layoutContactList;
|
||||
protected LinearLayout layoutSearchList;
|
||||
protected TextView tvMemberslist;
|
||||
protected TextView tvMembersLast;
|
||||
protected TextView tvMembersSpecialGz;
|
||||
|
||||
protected boolean isInvite;
|
||||
|
||||
protected int type;// 0 创建群 选好友, 1 转发消息 选好友
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
// isInvite = getIntent().getBooleanExtra("isinvite", false);
|
||||
rootView = initViewAndGetRootView(savedInstanceState);
|
||||
checkViews();
|
||||
setContentView(rootView);
|
||||
viewModel = new ViewModelProvider(this).get(ContactViewModel.class);
|
||||
searchViewModel = new ViewModelProvider(this).get(SearchViewModel.class);
|
||||
|
||||
initData();
|
||||
initView();
|
||||
|
||||
updateView();
|
||||
}
|
||||
|
||||
protected abstract View initViewAndGetRootView(Bundle savedInstanceState);
|
||||
|
||||
protected abstract List<ContactFriendBean> getFollowList(); //获取关注列表
|
||||
|
||||
public void updateView() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected void checkViews() {
|
||||
Objects.requireNonNull(rootView);
|
||||
Objects.requireNonNull(titleBar);
|
||||
Objects.requireNonNull(rvSelected);
|
||||
Objects.requireNonNull(emptyGroup);
|
||||
Objects.requireNonNull(contactListView);
|
||||
}
|
||||
|
||||
protected ArrayList<String> listAccount = new ArrayList<>();
|
||||
protected ArrayList<String> listname = new ArrayList<>();
|
||||
|
||||
protected void initView() {
|
||||
configTitle(titleBar);
|
||||
ContactActions actions = new ContactActions();
|
||||
if (type == 1) { //单选
|
||||
actions.addContactListener(
|
||||
IViewTypeConstant.CONTACT_FRIEND,
|
||||
(position, data) -> {
|
||||
FriendInfo friendInfo = ((ContactFriendBean) data).data;
|
||||
//转发选取一个结束
|
||||
Intent result = new Intent();
|
||||
// if (!selectedListAdapter.getSelectedFriends().isEmpty()) {
|
||||
// result.putExtra(REQUEST_CONTACT_SELECTOR_KEY, getSelectedAccount());
|
||||
// result.putExtra(KEY_REQUEST_SELECTOR_NAME, getSelectedName());
|
||||
//// if (enableReturnName) {
|
||||
//// result.putExtra(KEY_REQUEST_SELECTOR_NAME, getSelectedName());
|
||||
//// }
|
||||
// }
|
||||
listAccount.clear();
|
||||
listname.clear();
|
||||
listAccount.add(friendInfo.getAccount());
|
||||
listname.add(friendInfo.getName());
|
||||
result.putExtra(REQUEST_CONTACT_SELECTOR_KEY, listAccount);
|
||||
result.putExtra(KEY_REQUEST_SELECTOR_NAME, listname);
|
||||
setResult(RESULT_OK, result);
|
||||
finish();
|
||||
// XKitRouter.withKey(RouterConstant.PATH_FUN_CHAT_P2P_PAGE)
|
||||
// .withParam(RouterConstant.CHAT_ID_KRY, friendInfo.getAccount())
|
||||
// .withContext(requireActivity())
|
||||
// .navigate();
|
||||
// XKitRouter.withKey(RouterConstant.PATH_FUN_USER_INFO_PAGE)
|
||||
// .withContext(requireContext())
|
||||
// .withParam(RouterConstant.KEY_ACCOUNT_ID_KEY, friendInfo.getAccount())
|
||||
// .navigate();
|
||||
});
|
||||
} else {
|
||||
actions.addSelectorListener(
|
||||
IViewTypeConstant.CONTACT_FRIEND,
|
||||
(selector, data) -> {
|
||||
if (selector) {
|
||||
if (selectedListAdapter.getItemCount() >= maxSelectCount
|
||||
&& !selectFinalCheckCountEnable) {
|
||||
Toast.makeText(
|
||||
this,
|
||||
getString(
|
||||
R.string.contact_selector_max_count, String.valueOf(maxSelectCount)),
|
||||
Toast.LENGTH_LONG)
|
||||
.show();
|
||||
((ContactFriendBean) data).setSelected(false);
|
||||
contactListView.updateContactData(data);
|
||||
lastContactView.updateContactData(data);
|
||||
searchContactView.updateContactData(data);
|
||||
loveContactView.updateContactData(data);
|
||||
} else {
|
||||
((ContactFriendBean) data).setSelected(true);
|
||||
contactListView.updateContactData(data);
|
||||
lastContactView.updateContactData(data);
|
||||
searchContactView.updateContactData(data);
|
||||
loveContactView.updateContactData(data);
|
||||
selectedListAdapter.addFriend((ContactFriendBean) data);
|
||||
|
||||
}
|
||||
} else {
|
||||
((ContactFriendBean) data).setSelected(false);
|
||||
selectedListAdapter.removeFriend((ContactFriendBean) data);
|
||||
contactListView.updateContactData(data);
|
||||
lastContactView.updateContactData(data);
|
||||
loveContactView.updateContactData(data);
|
||||
searchContactView.updateContactData(data);
|
||||
}
|
||||
// titleBar.setActionText(getString(R.string.selector_sure_without_num));
|
||||
// int count = selectedListAdapter.getItemCount();
|
||||
// if (count <= 0) {
|
||||
// titleBar.setActionText(getString(R.string.selector_sure_without_num));
|
||||
// } else {
|
||||
// titleBar.setActionText(
|
||||
// String.format(
|
||||
// getString(R.string.selector_sure), selectedListAdapter.getItemCount()));
|
||||
// }
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
contactListView.setContactAction(actions);
|
||||
lastContactView.setContactAction(actions);
|
||||
searchContactView.setContactAction(actions);
|
||||
loveContactView.setContactAction(actions);
|
||||
//top selected list
|
||||
LinearLayoutManager layoutManager =
|
||||
new LinearLayoutManager(this, RecyclerView.HORIZONTAL, false);
|
||||
rvSelected.setLayoutManager(layoutManager);
|
||||
selectedListAdapter = getSelectedListAdapter();
|
||||
selectedListAdapter.setItemClickListener(
|
||||
item -> {
|
||||
item.setSelected(false);
|
||||
contactListView.updateContactData(item);
|
||||
lastContactView.updateContactData(item);
|
||||
loveContactView.updateContactData(item);
|
||||
searchContactView.updateContactData(item);
|
||||
//int count = selectedListAdapter.getItemCount();
|
||||
// titleBar.setActionText(getString(R.string.selector_sure_without_num));
|
||||
// if (count <= 0) {
|
||||
// titleBar.setActionText(getString(R.string.selector_sure_without_num));
|
||||
// } else {
|
||||
// titleBar.setActionText(
|
||||
// String.format(
|
||||
// getString(R.string.selector_sure), selectedListAdapter.getItemCount()));
|
||||
// }
|
||||
});
|
||||
rvSelected.setAdapter(selectedListAdapter);
|
||||
editSearch.setOnEditorActionListener((textView, actionId, keyEvent) ->
|
||||
{
|
||||
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
|
||||
String search = textView.getEditableText().toString();
|
||||
//搜索好友
|
||||
searchViewModel.queryFriend(search);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
editSearch.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
if (TextUtils.isEmpty(editSearch.getText().toString())) {
|
||||
ivClean.setVisibility(View.GONE);
|
||||
layoutContactList.setVisibility(View.VISIBLE);
|
||||
layoutSearchList.setVisibility(View.GONE);
|
||||
hideSoftInput(BaseContactSelectorActivity.this);
|
||||
} else {
|
||||
ivClean.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
ivClean.setOnClickListener(view -> editSearch.setText(""));
|
||||
}
|
||||
|
||||
public void hideSoftInput(Activity activity) {
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
|
||||
if (getCurrentFocus() != null && null != imm) {
|
||||
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected BaseSelectedListAdapter<? extends ViewBinding> getSelectedListAdapter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// protected void configTitle(BackTitleBar titleBar) {
|
||||
// titleBar
|
||||
// .setOnBackIconClickListener(v -> onBackPressed())
|
||||
// .setTitle(R.string.select)
|
||||
// .setActionText(getString(R.string.selector_sure_without_num))
|
||||
// .setActionTextColor(getResources().getColor(R.color.color_6b3689))
|
||||
// .setActionListener(
|
||||
// v -> {
|
||||
// if (checkNetworkEnable && !NetworkUtils.isConnected()) {
|
||||
// Toast.makeText(this, R.string.contact_network_error_tip, Toast.LENGTH_SHORT).show();
|
||||
// return;
|
||||
// }
|
||||
// List<String> select = getSelectedAccount();
|
||||
// if (select.size() < 1) {
|
||||
// Toast.makeText(this, getString(R.string.select_empty_tips), Toast.LENGTH_LONG)
|
||||
// .show();
|
||||
// return;
|
||||
// }
|
||||
// if (selectedListAdapter.getItemCount() >= maxSelectCount
|
||||
// && selectFinalCheckCountEnable) {
|
||||
// Toast.makeText(this, R.string.contact_selector_over_count, Toast.LENGTH_LONG)
|
||||
// .show();
|
||||
// return;
|
||||
// }
|
||||
// Intent result = new Intent();
|
||||
// if (!selectedListAdapter.getSelectedFriends().isEmpty()) {
|
||||
// result.putExtra(REQUEST_CONTACT_SELECTOR_KEY, getSelectedAccount());
|
||||
// if (enableReturnName) {
|
||||
// result.putExtra(KEY_REQUEST_SELECTOR_NAME, getSelectedName());
|
||||
// }
|
||||
// }
|
||||
// setResult(RESULT_OK, result);
|
||||
// finish();
|
||||
// });
|
||||
// }
|
||||
|
||||
protected void configTitle(BackTitleBar titleBar) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected void initData() {
|
||||
filterUser = getIntent().getStringArrayListExtra(RouterConstant.SELECTOR_CONTACT_FILTER_KEY);
|
||||
selectFinalCheckCountEnable =
|
||||
getIntent()
|
||||
.getBooleanExtra(RouterConstant.KEY_CONTACT_SELECTOR_FINAL_CHECK_COUNT_ENABLE, false);
|
||||
checkNetworkEnable =
|
||||
getIntent().getBooleanExtra(RouterConstant.KEY_CONTACT_SELECTOR_CHECK_NETWORK_ENABLE, true);
|
||||
maxSelectCount =
|
||||
getIntent()
|
||||
.getIntExtra(RouterConstant.KEY_CONTACT_SELECTOR_MAX_COUNT, DEFAULT_MAX_SELECT_COUNT);
|
||||
type = getIntent().getIntExtra("type", 0);
|
||||
enableReturnName =
|
||||
getIntent().getBooleanExtra(RouterConstant.KEY_REQUEST_SELECTOR_NAME_ENABLE, false);
|
||||
viewModel
|
||||
.getContactLiveData()
|
||||
.observe(
|
||||
this,
|
||||
contactBeansResult -> {
|
||||
if (contactBeansResult.getLoadStatus() == LoadStatus.Success) {
|
||||
List<ContactFriendBean> accountList = filterUser(contactBeansResult.getData());
|
||||
tvMemberslist.setText(String.format(getString(R.string.fun_contactselector_members), accountList.size()));
|
||||
contactListView.onFriendDataSourceChanged(accountList);
|
||||
showEmptyView(accountList == null || accountList.size() < 1);
|
||||
}
|
||||
});
|
||||
viewModel.fetchContactList();
|
||||
|
||||
|
||||
List<RecentContact> recentContact = NIMClient.getService(MsgService.class).queryRecentContactsBlock();
|
||||
if (recentContact != null && recentContact.size() > 0) {
|
||||
List<ContactFriendBean> list = convertConvacationList(recentContact);
|
||||
if (list.size() > 0) {
|
||||
tvMembersLast.setVisibility(View.VISIBLE);
|
||||
lastContactView.setVisibility(View.VISIBLE);
|
||||
tvMembersLast.setText(String.format(getString(R.string.fun_contactselector_last), list.size()));
|
||||
lastContactView.onFriendDataSourceChanged(list);
|
||||
}
|
||||
}
|
||||
|
||||
searchViewModel.getQueryLiveData().observe(this, result -> {
|
||||
if (result.getLoadStatus() == LoadStatus.Success) {
|
||||
if (result.getData() != null && result.getData().size() > 0) {
|
||||
layoutSearchList.setVisibility(View.VISIBLE);
|
||||
layoutContactList.setVisibility(View.GONE);
|
||||
searchContactView.onFriendDataSourceChanged(convertSearchList(result.getData()));
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
List<ContactFriendBean> DATA = getFollowList();
|
||||
Log.i("D", DATA + "");
|
||||
if (lastContactView != null && DATA.size() > 0) {
|
||||
tvMembersSpecialGz.setVisibility(View.VISIBLE);
|
||||
loveContactView.setVisibility(View.VISIBLE);
|
||||
tvMembersSpecialGz.setText(String.format(getString(R.string.fun_contactselector_mylove), DATA.size()));
|
||||
loveContactView.onFriendDataSourceChanged(getFollowList());
|
||||
}
|
||||
}
|
||||
|
||||
// public List<ContactFriendBean> convertConvacationList(List<ConversationBean> list) {
|
||||
// List<ContactFriendBean> contactFriendBeans = new ArrayList<>();
|
||||
//
|
||||
// for (ConversationBean bean : list) {
|
||||
// ConversationInfo conversationInfo = bean.infoData;
|
||||
// if (conversationInfo.getFriendInfo() != null) {
|
||||
// FriendInfo friendInfo = conversationInfo.getFriendInfo();
|
||||
// friendInfo.setUserInfo(conversationInfo.getUserInfo());
|
||||
// ContactFriendBean item = new ContactFriendBean(friendInfo);
|
||||
// contactFriendBeans.add(item);
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// return contactFriendBeans;
|
||||
// }
|
||||
|
||||
public List<ContactFriendBean> convertConvacationList(List<RecentContact> list) {
|
||||
List<ContactFriendBean> contactFriendBeans = new ArrayList<>();
|
||||
for (RecentContact recentContact : list) {
|
||||
if (recentContact.getSessionType() == SessionTypeEnum.P2P) {
|
||||
if (ContactRepo.isFriend(recentContact.getContactId())) {
|
||||
FriendInfo friendInfo = ContactRepo.getFriend(recentContact.getContactId());
|
||||
friendInfo.setUserInfo(ContactRepo.getUserInfo(recentContact.getContactId()));
|
||||
ContactFriendBean item = new ContactFriendBean(friendInfo);
|
||||
contactFriendBeans.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
return contactFriendBeans;
|
||||
}
|
||||
|
||||
public List<ContactFriendBean> convertSearchList(List<BaseBean> list) {
|
||||
|
||||
List<ContactFriendBean> contactFriendBeans = new ArrayList<>();
|
||||
LinkedList<ContactFriendBean> selected = selectedListAdapter.getSelectedFriends();
|
||||
for (BaseBean bean : list) {
|
||||
if (bean instanceof SearchFriendBean) {
|
||||
SearchFriendBean searchFriendBean = (SearchFriendBean) bean;
|
||||
FriendInfo friendInfo = searchFriendBean.friendSearchInfo.getFriendInfo();
|
||||
ContactFriendBean item = new ContactFriendBean(friendInfo);
|
||||
if (selected.size() > 0 && selected.contains(item)) {
|
||||
contactFriendBeans.add(selected.get(selected.indexOf(item)));
|
||||
} else {
|
||||
contactFriendBeans.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
return contactFriendBeans;
|
||||
}
|
||||
|
||||
protected void showEmptyView(boolean show) {
|
||||
if (show) {
|
||||
emptyGroup.setVisibility(View.VISIBLE);
|
||||
contactListView.setVisibility(View.GONE);
|
||||
} else {
|
||||
contactListView.setVisibility(View.VISIBLE);
|
||||
emptyGroup.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
protected List<ContactFriendBean> filterUser(List<ContactFriendBean> source) {
|
||||
if (filterUser == null || filterUser.isEmpty()) {
|
||||
return source;
|
||||
}
|
||||
List<ContactFriendBean> result = new ArrayList<>(source);
|
||||
for (ContactFriendBean friendBean : source) {
|
||||
if (filterUser.contains(friendBean.data.getAccount())) {
|
||||
result.remove(friendBean);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
protected List<ContactFriendBean> getLastContactList() {
|
||||
return lastContactView.getAdapter().getFriendList();
|
||||
}
|
||||
|
||||
protected List<ContactFriendBean> getContactAllList() {
|
||||
return contactListView.getAdapter().getFriendList();
|
||||
}
|
||||
|
||||
protected ArrayList<String> getSelectedAccount() {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
for (ContactFriendBean bean : selectedListAdapter.getSelectedFriends()) {
|
||||
result.add(bean.data.getAccount());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected ArrayList<String> getSelectedName() {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
for (ContactFriendBean bean : selectedListAdapter.getSelectedFriends()) {
|
||||
String name = bean.data.getName();
|
||||
result.add(TextUtils.isEmpty(name) ? bean.data.getAccount() : name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected ArrayList<String> getSelectedAvatar() {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
for (ContactFriendBean bean : selectedListAdapter.getSelectedFriends()) {
|
||||
if (bean.data.getUserInfo() == null) {
|
||||
continue;
|
||||
}
|
||||
String avatar = bean.data.getUserInfo().getAvatar();
|
||||
result.add(TextUtils.isEmpty(avatar) ? "" : avatar);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (null != this.getCurrentFocus()) {
|
||||
/**
|
||||
* 点击空白位置 隐藏软键盘
|
||||
*/
|
||||
InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
|
||||
return mInputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.selector;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.viewbinding.ViewBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactFriendBean;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendInfo;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public abstract class BaseSelectedListAdapter<R extends ViewBinding>
|
||||
extends RecyclerView.Adapter<BaseSelectedListAdapter.SelectedViewHolder<R>> {
|
||||
|
||||
protected final LinkedList<ContactFriendBean> selectedFriends;
|
||||
|
||||
protected ItemClickListener itemClickListener;
|
||||
|
||||
public BaseSelectedListAdapter() {
|
||||
selectedFriends = new LinkedList<>();
|
||||
}
|
||||
|
||||
protected abstract R provideViewBinding(@NonNull ViewGroup parent, int viewType);
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public final SelectedViewHolder<R> onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
return new SelectedViewHolder<>(provideViewBinding(parent, viewType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onBindViewHolder(@NonNull SelectedViewHolder<R> holder, int position) {
|
||||
ContactFriendBean bean = selectedFriends.get(position);
|
||||
if (bean == null) {
|
||||
return;
|
||||
}
|
||||
FriendInfo friendData = bean.data;
|
||||
handleBindViewHolder(holder, bean, friendData);
|
||||
}
|
||||
|
||||
protected abstract void handleBindViewHolder(
|
||||
SelectedViewHolder<R> holder, ContactFriendBean bean, FriendInfo friendData);
|
||||
|
||||
public void setItemClickListener(ItemClickListener itemClickListener) {
|
||||
this.itemClickListener = itemClickListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return selectedFriends.size();
|
||||
}
|
||||
|
||||
public LinkedList<ContactFriendBean> getSelectedFriends() {
|
||||
return selectedFriends;
|
||||
}
|
||||
|
||||
public void addFriend(ContactFriendBean friend) {
|
||||
int index = selectedFriends.size();
|
||||
selectedFriends.add(friend);
|
||||
notifyItemInserted(index);
|
||||
}
|
||||
|
||||
public void removeFriend(ContactFriendBean friend) {
|
||||
int pos = selectedFriends.indexOf(friend);
|
||||
if (pos >= 0) {
|
||||
selectedFriends.remove(friend);
|
||||
notifyItemRemoved(pos);
|
||||
}
|
||||
}
|
||||
|
||||
protected static class SelectedViewHolder<R extends ViewBinding> extends RecyclerView.ViewHolder {
|
||||
|
||||
public R binding;
|
||||
|
||||
public SelectedViewHolder(@NonNull R binding) {
|
||||
super(binding.getRoot());
|
||||
this.binding = binding;
|
||||
}
|
||||
}
|
||||
|
||||
public interface ItemClickListener {
|
||||
void onItemClick(ContactFriendBean item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.team;
|
||||
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.FetchResult;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.LoadStatus;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.activity.BaseListActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.BaseListActivityLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactTeamBean;
|
||||
import com.netease.yunxin.kit.corekit.im.IMKitClient;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
public abstract class BaseTeamListActivity extends BaseListActivity {
|
||||
|
||||
protected TeamListViewModel viewModel;
|
||||
|
||||
protected boolean isSelector;
|
||||
|
||||
protected abstract void configViewHolderFactory();
|
||||
|
||||
@Override
|
||||
protected void initView() {
|
||||
configTitle(binding);
|
||||
configViewHolderFactory();
|
||||
}
|
||||
|
||||
protected void configTitle(BaseListActivityLayoutBinding binding) {
|
||||
binding.title.setTitle(R.string.my_team);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initData() {
|
||||
isSelector = getIntent().getBooleanExtra(RouterConstant.KEY_TEAM_LIST_SELECT, false);
|
||||
viewModel = new ViewModelProvider(this).get(TeamListViewModel.class);
|
||||
configRoutePath(viewModel);
|
||||
viewModel
|
||||
.getFetchResult()
|
||||
.observe(
|
||||
this,
|
||||
result -> {
|
||||
if (result.getLoadStatus() == LoadStatus.Success) {
|
||||
binding.contactListView.clearContactData();
|
||||
binding.contactListView.addContactData(result.getData());
|
||||
} else if (result.getLoadStatus() == LoadStatus.Finish) {
|
||||
if (result.getType() == FetchResult.FetchType.Add) {
|
||||
binding.contactListView.addForwardContactData(result.getData());
|
||||
binding.contactListView.scrollToPosition(0);
|
||||
} else if (result.getType() == FetchResult.FetchType.Remove) {
|
||||
binding.contactListView.removeContactData(result.getData());
|
||||
}
|
||||
}
|
||||
// Collections.sort(binding.contactListView.getAdapter().getDataList(), teambeanComparator);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
viewModel.fetchTeamList();
|
||||
}
|
||||
|
||||
protected void configRoutePath(TeamListViewModel viewModel) {
|
||||
}
|
||||
|
||||
|
||||
//按照群聊时间
|
||||
// public Comparator<BaseContactBean> teambeanComparator =
|
||||
// (bean1, bean2) -> {
|
||||
// int result = 1;
|
||||
// if (bean1 == null) {
|
||||
// result = 1;
|
||||
// } else if (bean2 == null) {
|
||||
// result = -1;
|
||||
// } else if (bean1 instanceof ContactTeamBean && bean2 instanceof ContactTeamBean) { //群聊
|
||||
// ContactTeamBean teamBean1 = (ContactTeamBean) bean1;
|
||||
// ContactTeamBean teamBean2 = (ContactTeamBean) bean2;
|
||||
// long chattime = teamBean1.getConversationTime() - teamBean2.getConversationTime();
|
||||
// return (chattime > 0 ? -1 : 1);
|
||||
// } else {
|
||||
// result = -1;
|
||||
// }
|
||||
// return result;
|
||||
// };
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.team;
|
||||
|
||||
import static com.netease.yunxin.kit.contactkit.ui.ContactConstant.LIB_TAG;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import com.netease.nimlib.sdk.Observer;
|
||||
import com.netease.nimlib.sdk.team.model.Team;
|
||||
import com.netease.yunxin.kit.alog.ALog;
|
||||
import com.netease.yunxin.kit.chatkit.repo.TeamObserverRepo;
|
||||
import com.netease.yunxin.kit.chatkit.repo.TeamRepo;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.BaseViewModel;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.FetchResult;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.LoadStatus;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactTeamBean;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FetchCallback;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TeamListViewModel extends BaseViewModel {
|
||||
private final String TAG = "TeamListViewModel";
|
||||
|
||||
private final MutableLiveData<FetchResult<List<ContactTeamBean>>> resultLiveData =
|
||||
new MutableLiveData<>();
|
||||
private final FetchResult<List<ContactTeamBean>> fetchResult =
|
||||
new FetchResult<>(LoadStatus.Finish);
|
||||
private final List<ContactTeamBean> teamBeanList = new ArrayList<>();
|
||||
private final Observer<List<Team>> teamUpdateObserver;
|
||||
private final Observer<Team> teamRemoveObserver;
|
||||
private String defaultRoutePath = RouterConstant.PATH_CHAT_TEAM_PAGE;
|
||||
|
||||
public void configRoutePath(String path) {
|
||||
this.defaultRoutePath = path;
|
||||
}
|
||||
|
||||
public MutableLiveData<FetchResult<List<ContactTeamBean>>> getFetchResult() {
|
||||
return resultLiveData;
|
||||
}
|
||||
|
||||
public TeamListViewModel() {
|
||||
teamUpdateObserver = this::updateTeamData;
|
||||
teamRemoveObserver = this::removeTeamData;
|
||||
TeamObserverRepo.registerTeamUpdateObserver(teamUpdateObserver);
|
||||
TeamObserverRepo.registerTeamRemoveObserver(teamRemoveObserver);
|
||||
}
|
||||
|
||||
public void fetchTeamList() {
|
||||
ALog.d(LIB_TAG, TAG, "fetchTeamList");
|
||||
fetchResult.setStatus(LoadStatus.Loading);
|
||||
resultLiveData.postValue(fetchResult);
|
||||
TeamRepo.getTeamList(
|
||||
new FetchCallback<List<Team>>() {
|
||||
@Override
|
||||
public void onSuccess(List<Team> param) {
|
||||
ALog.d(
|
||||
LIB_TAG, TAG, "fetchTeamList,onSuccess:" + (param == null ? "null" : param.size()));
|
||||
teamBeanList.clear();
|
||||
if (param != null && param.size() > 0) {
|
||||
fetchResult.setStatus(LoadStatus.Success);
|
||||
for (Team teamInfo : param) {
|
||||
ContactTeamBean teamBean = new ContactTeamBean(teamInfo);
|
||||
teamBean.router = defaultRoutePath;
|
||||
teamBeanList.add(0, teamBean);
|
||||
}
|
||||
fetchResult.setData(teamBeanList);
|
||||
} else {
|
||||
fetchResult.setData(null);
|
||||
fetchResult.setStatus(LoadStatus.Success);
|
||||
}
|
||||
resultLiveData.postValue(fetchResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchTeamList,onFailed:" + code);
|
||||
fetchResult.setError(code, "");
|
||||
resultLiveData.postValue(fetchResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchTeamList,onException");
|
||||
fetchResult.setError(-1, "");
|
||||
resultLiveData.postValue(fetchResult);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void removeTeamData(Team teamInfo) {
|
||||
if (teamInfo != null) {
|
||||
ALog.d(LIB_TAG, TAG, "removeTeamData:" + teamInfo.getId());
|
||||
List<ContactTeamBean> remove = new ArrayList<>();
|
||||
for (ContactTeamBean bean : teamBeanList) {
|
||||
if (TextUtils.equals(teamInfo.getId(), bean.data.getId())) {
|
||||
remove.add(bean);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (remove.size() > 0) {
|
||||
fetchResult.setFetchType(FetchResult.FetchType.Remove);
|
||||
fetchResult.setData(remove);
|
||||
resultLiveData.postValue(fetchResult);
|
||||
} else {
|
||||
fetchTeamList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTeamData(List<Team> teamInfoList) {
|
||||
if (teamInfoList != null && !teamInfoList.isEmpty()) {
|
||||
ALog.d(LIB_TAG, TAG, "updateTeamData:" + teamInfoList.size());
|
||||
List<ContactTeamBean> add = new ArrayList<>();
|
||||
for (Team teamInfo : teamInfoList) {
|
||||
boolean has = false;
|
||||
for (ContactTeamBean bean : teamBeanList) {
|
||||
if (TextUtils.equals(teamInfo.getId(), bean.data.getId())) {
|
||||
has = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!has) {
|
||||
ContactTeamBean teamBean = new ContactTeamBean(teamInfo);
|
||||
teamBean.router = defaultRoutePath;
|
||||
add.add(teamBean);
|
||||
teamBeanList.add(0, teamBean);
|
||||
}
|
||||
}
|
||||
|
||||
if (add.size() > 0) {
|
||||
fetchResult.setFetchType(FetchResult.FetchType.Add);
|
||||
fetchResult.setData(add);
|
||||
resultLiveData.postValue(fetchResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
super.onCleared();
|
||||
TeamObserverRepo.unregisterTeamUpdateObserver(teamUpdateObserver);
|
||||
TeamObserverRepo.unregisterTeamRemoveObserver(teamRemoveObserver);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.userinfo;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.netease.yunxin.kit.common.ui.activities.BaseActivity;
|
||||
import com.netease.yunxin.kit.common.ui.widgets.BackTitleBar;
|
||||
import com.netease.yunxin.kit.common.ui.widgets.CleanableEditText;
|
||||
import com.netease.yunxin.kit.common.utils.NetworkUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class BaseCommentActivity extends BaseActivity {
|
||||
|
||||
public static final String REQUEST_COMMENT_NAME_KEY = "comment";
|
||||
|
||||
private View rootView;
|
||||
protected CleanableEditText edtComment;
|
||||
protected BackTitleBar titleBar;
|
||||
|
||||
protected abstract View initViewAndGetRootView(Bundle savedInstanceState);
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
rootView = initViewAndGetRootView(savedInstanceState);
|
||||
checkViews();
|
||||
setContentView(rootView);
|
||||
initView();
|
||||
}
|
||||
|
||||
protected void checkViews() {
|
||||
Objects.requireNonNull(rootView);
|
||||
Objects.requireNonNull(edtComment);
|
||||
Objects.requireNonNull(titleBar);
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
String comment = getIntent().getStringExtra(REQUEST_COMMENT_NAME_KEY);
|
||||
comment = comment == null ? "" : comment;
|
||||
edtComment.setText(comment);
|
||||
int textLength = edtComment.getBinding().editText.length();
|
||||
edtComment.getBinding().editText.setSelection(textLength);
|
||||
edtComment.getBinding().editText.requestFocus();
|
||||
configTitle(titleBar);
|
||||
}
|
||||
|
||||
protected void configTitle(BackTitleBar titleBar) {
|
||||
titleBar
|
||||
.setTitle(R.string.comment_name)
|
||||
.setOnBackIconClickListener(v -> onBackPressed())
|
||||
.setActionText(R.string.save)
|
||||
.setActionListener(
|
||||
v -> {
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
Toast.makeText(this, R.string.contact_network_error_tip, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
Intent intent = new Intent();
|
||||
if (!TextUtils.isEmpty(edtComment.getText())) {
|
||||
intent.putExtra(REQUEST_COMMENT_NAME_KEY, edtComment.getText());
|
||||
}
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.userinfo;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import com.netease.yunxin.kit.common.ui.activities.BaseActivity;
|
||||
import com.netease.yunxin.kit.common.ui.dialog.BottomConfirmDialog;
|
||||
import com.netease.yunxin.kit.common.ui.dialog.ConfirmListener;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.LoadStatus;
|
||||
import com.netease.yunxin.kit.common.ui.widgets.BackTitleBar;
|
||||
import com.netease.yunxin.kit.common.utils.NetworkUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactUserInfoBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactInfoView;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendVerifyType;
|
||||
import com.netease.yunxin.kit.corekit.im.model.UserInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FetchCallback;
|
||||
import com.netease.yunxin.kit.corekit.im.utils.RouterConstant;
|
||||
import com.netease.yunxin.kit.corekit.route.XKitRouter;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class BaseUserInfoActivity extends BaseActivity {
|
||||
protected UserInfoViewModel viewModel;
|
||||
protected ContactUserInfoBean userInfoData;
|
||||
protected String accId;
|
||||
|
||||
private View rootView;
|
||||
protected BackTitleBar titleBar;
|
||||
protected ContactInfoView contactInfoView;
|
||||
|
||||
protected ActivityResultLauncher<Intent> commentLauncher;
|
||||
|
||||
protected abstract View initViewAndGetRootView(Bundle savedInstanceState);
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
rootView = initViewAndGetRootView(savedInstanceState);
|
||||
checkViews();
|
||||
setContentView(rootView);
|
||||
titleBar.setOnBackIconClickListener(v -> onBackPressed());
|
||||
initView();
|
||||
initData();
|
||||
registerResult();
|
||||
}
|
||||
|
||||
protected void checkViews() {
|
||||
Objects.requireNonNull(rootView);
|
||||
Objects.requireNonNull(titleBar);
|
||||
Objects.requireNonNull(contactInfoView);
|
||||
}
|
||||
|
||||
private void registerResult() {
|
||||
commentLauncher =
|
||||
registerForActivityResult(
|
||||
new ActivityResultContracts.StartActivityForResult(),
|
||||
result -> {
|
||||
if (result.getResultCode() == BaseCommentActivity.RESULT_OK
|
||||
&& result.getData() != null) {
|
||||
String comment =
|
||||
result.getData().getStringExtra(BaseCommentActivity.REQUEST_COMMENT_NAME_KEY);
|
||||
userInfoData.friendInfo.setAlias(comment);
|
||||
contactInfoView.setData(userInfoData);
|
||||
viewModel.updateAlias(userInfoData.data.getAccount(), comment);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
contactInfoView.setUserCallback(
|
||||
new ContactInfoView.IUserCallback() {
|
||||
@Override
|
||||
public void goChat() {
|
||||
if (userInfoData == null || userInfoData.data == null) {
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
Toast.makeText(
|
||||
BaseUserInfoActivity.this,
|
||||
R.string.contact_network_error_tip,
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
BaseUserInfoActivity.this.goChat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFriend() {
|
||||
if (userInfoData == null || userInfoData.data == null) {
|
||||
return;
|
||||
}
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
Toast.makeText(
|
||||
BaseUserInfoActivity.this, R.string.contact_network_error_tip, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
addNewFriend();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openMessageNotify(boolean open) {
|
||||
//todo 打开或者关闭消息通知
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBlackList(boolean add) {
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
Toast.makeText(
|
||||
BaseUserInfoActivity.this, R.string.contact_network_error_tip, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
if (userInfoData == null || userInfoData.data == null) {
|
||||
return;
|
||||
}
|
||||
if (add) {
|
||||
viewModel.addBlack(userInfoData.data.getAccount());
|
||||
} else {
|
||||
viewModel.removeBlack(userInfoData.data.getAccount());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
contactInfoView.setCommentClickListener(
|
||||
v -> {
|
||||
if (userInfoData == null || userInfoData.data == null) {
|
||||
return;
|
||||
}
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(this, getCommentActivity());
|
||||
intent.putExtra(
|
||||
BaseCommentActivity.REQUEST_COMMENT_NAME_KEY, userInfoData.friendInfo.getAlias());
|
||||
commentLauncher.launch(intent);
|
||||
});
|
||||
|
||||
contactInfoView.setDeleteClickListener(
|
||||
v -> {
|
||||
if (userInfoData == null || userInfoData.data == null) {
|
||||
return;
|
||||
}
|
||||
showDeleteConfirmDialog();
|
||||
});
|
||||
}
|
||||
|
||||
protected void goChat() {
|
||||
XKitRouter.withKey(RouterConstant.PATH_CHAT_P2P_PAGE)
|
||||
.withParam(RouterConstant.CHAT_ID_KRY, userInfoData.data.getAccount())
|
||||
.withContext(BaseUserInfoActivity.this)
|
||||
.navigate();
|
||||
finish();
|
||||
}
|
||||
|
||||
protected Class<? extends Activity> getCommentActivity() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void showDeleteConfirmDialog() {
|
||||
BottomConfirmDialog bottomConfirmDialog = new BottomConfirmDialog();
|
||||
bottomConfirmDialog
|
||||
.setTitleStr(
|
||||
String.format(getString(R.string.delete_contact_account), userInfoData.getName()))
|
||||
.setPositiveStr(getString(R.string.delete_friend))
|
||||
.setNegativeStr(getString(R.string.cancel))
|
||||
.setConfirmListener(
|
||||
new ConfirmListener() {
|
||||
@Override
|
||||
public void onNegative() {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPositive() {
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
Toast.makeText(
|
||||
BaseUserInfoActivity.this,
|
||||
R.string.contact_network_error_tip,
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
viewModel.deleteFriend(userInfoData.data.getAccount());
|
||||
finish();
|
||||
}
|
||||
})
|
||||
.show(getSupportFragmentManager());
|
||||
}
|
||||
|
||||
private void initData() {
|
||||
viewModel = new ViewModelProvider(this).get(UserInfoViewModel.class);
|
||||
accId = getIntent().getStringExtra(RouterConstant.KEY_ACCOUNT_ID_KEY);
|
||||
if (TextUtils.isEmpty(accId)) {
|
||||
finish();
|
||||
}
|
||||
viewModel.init(accId);
|
||||
viewModel
|
||||
.getFriendFetchResult()
|
||||
.observe(
|
||||
this,
|
||||
mapFetchResult -> {
|
||||
if (mapFetchResult.getLoadStatus() == LoadStatus.Success) {
|
||||
userInfoData = mapFetchResult.getData();
|
||||
contactInfoView.setData(userInfoData);
|
||||
} else {
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
Toast.makeText(this, R.string.contact_network_error_tip, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
viewModel
|
||||
.getUserInfoLiveData()
|
||||
.observe(
|
||||
this,
|
||||
userInfoResult -> {
|
||||
if (userInfoResult.getLoadStatus() == LoadStatus.Finish
|
||||
&& userInfoResult.getData() != null) {
|
||||
for (UserInfo userInfo : userInfoResult.getData()) {
|
||||
if (TextUtils.equals(userInfo.getAccount(), accId)) {
|
||||
if (userInfoData != null) {
|
||||
userInfoData.data = userInfo;
|
||||
contactInfoView.setData(userInfoData);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
Toast.makeText(this, R.string.contact_network_error_tip, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
viewModel
|
||||
.getFriendChangeLiveData()
|
||||
.observe(
|
||||
this,
|
||||
result -> {
|
||||
if (result.getLoadStatus() == LoadStatus.Finish) {
|
||||
viewModel.fetchData(accId);
|
||||
}
|
||||
});
|
||||
viewModel.fetchData(accId);
|
||||
}
|
||||
|
||||
private void addNewFriend() {
|
||||
viewModel.addFriend(
|
||||
userInfoData.data.getAccount(),
|
||||
FriendVerifyType.AgreeAdd,
|
||||
new FetchCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable Void param) {
|
||||
viewModel.fetchData(userInfoData.data.getAccount());
|
||||
Toast.makeText(
|
||||
BaseUserInfoActivity.this,
|
||||
getResources().getString(R.string.add_friend_operate_success),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
String tips = getResources().getString(R.string.add_friend_operate_fail);
|
||||
Toast.makeText(
|
||||
BaseUserInfoActivity.this,
|
||||
String.format(tips, String.valueOf(code)),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
String tips = getResources().getString(R.string.add_friend_operate_fail);
|
||||
Toast.makeText(
|
||||
BaseUserInfoActivity.this,
|
||||
String.format(tips, exception.getMessage()),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,338 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.userinfo;
|
||||
|
||||
import static com.netease.yunxin.kit.contactkit.ui.ContactConstant.LIB_TAG;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.netease.nimlib.sdk.NIMClient;
|
||||
import com.netease.nimlib.sdk.RequestCallback;
|
||||
import com.netease.nimlib.sdk.friend.FriendService;
|
||||
import com.netease.nimlib.sdk.friend.constant.VerifyType;
|
||||
import com.netease.nimlib.sdk.friend.model.AddFriendData;
|
||||
import com.netease.yunxin.kit.alog.ALog;
|
||||
import com.netease.yunxin.kit.chatkit.repo.ContactObserverRepo;
|
||||
import com.netease.yunxin.kit.chatkit.repo.ContactRepo;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.BaseViewModel;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.FetchResult;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.LoadStatus;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactUserInfoBean;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.model.FriendVerifyType;
|
||||
import com.netease.yunxin.kit.corekit.im.model.UserInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FetchCallback;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FriendChangeType;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FriendObserver;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.UserInfoObserver;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class UserInfoViewModel extends BaseViewModel {
|
||||
private final String TAG = "UserInfoViewModel";
|
||||
|
||||
private final MutableLiveData<FetchResult<ContactUserInfoBean>> friendLiveData =
|
||||
new MutableLiveData<>();
|
||||
private final FetchResult<ContactUserInfoBean> fetchResult = new FetchResult<>(LoadStatus.Finish);
|
||||
private final MutableLiveData<FetchResult<List<UserInfo>>> userInfoLiveData =
|
||||
new MutableLiveData<>();
|
||||
private final FetchResult<List<UserInfo>> userInfoFetchResult =
|
||||
new FetchResult<>(LoadStatus.Finish);
|
||||
|
||||
private final MutableLiveData<FetchResult<String>> friendChangeLiveData = new MutableLiveData<>();
|
||||
private final FetchResult<String> friendChangeFetchResult = new FetchResult<>(LoadStatus.Finish);
|
||||
|
||||
private String accountId;
|
||||
|
||||
public UserInfoViewModel() {
|
||||
registerObserver();
|
||||
}
|
||||
|
||||
public void init(String account) {
|
||||
accountId = account;
|
||||
}
|
||||
|
||||
private final UserInfoObserver userInfoObserver =
|
||||
userList -> {
|
||||
userInfoFetchResult.setLoadStatus(LoadStatus.Finish);
|
||||
userInfoFetchResult.setData(userList);
|
||||
userInfoFetchResult.setType(FetchResult.FetchType.Update);
|
||||
userInfoLiveData.setValue(userInfoFetchResult);
|
||||
};
|
||||
|
||||
private final FriendObserver friendObserver =
|
||||
(friendChangeType, accountList) -> {
|
||||
if (friendChangeType == FriendChangeType.Add
|
||||
|| friendChangeType == FriendChangeType.Delete) {
|
||||
for (String account : accountList) {
|
||||
if (TextUtils.equals(accountId, account)) {
|
||||
friendChangeFetchResult.setData(account);
|
||||
friendChangeFetchResult.setLoadStatus(LoadStatus.Finish);
|
||||
if (friendChangeType == FriendChangeType.Add) {
|
||||
friendChangeFetchResult.setFetchType(FetchResult.FetchType.Add);
|
||||
} else {
|
||||
friendChangeFetchResult.setFetchType(FetchResult.FetchType.Remove);
|
||||
}
|
||||
friendChangeLiveData.setValue(friendChangeFetchResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void registerObserver() {
|
||||
ContactObserverRepo.registerUserInfoObserver(userInfoObserver);
|
||||
ContactObserverRepo.registerFriendObserver(friendObserver);
|
||||
}
|
||||
|
||||
public MutableLiveData<FetchResult<ContactUserInfoBean>> getFriendFetchResult() {
|
||||
return friendLiveData;
|
||||
}
|
||||
|
||||
public MutableLiveData<FetchResult<List<UserInfo>>> getUserInfoLiveData() {
|
||||
return userInfoLiveData;
|
||||
}
|
||||
|
||||
public MutableLiveData<FetchResult<String>> getFriendChangeLiveData() {
|
||||
return friendChangeLiveData;
|
||||
}
|
||||
|
||||
public void fetchData(String account) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchData:" + account);
|
||||
if (TextUtils.isEmpty(account)) {
|
||||
return;
|
||||
}
|
||||
List<String> accountList = new ArrayList<>();
|
||||
accountList.add(account);
|
||||
ContactRepo.fetchFriend(
|
||||
account,
|
||||
new FetchCallback<FriendInfo>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable FriendInfo param) {
|
||||
ALog.d(
|
||||
LIB_TAG,
|
||||
TAG,
|
||||
"fetchData,onSuccess:" + (param == null ? "null" : param.getAccount()));
|
||||
if (param != null) {
|
||||
ContactUserInfoBean userInfo = new ContactUserInfoBean(param.getUserInfo());
|
||||
userInfo.friendInfo = param;
|
||||
userInfo.isBlack = isBlack(account);
|
||||
userInfo.isFriend = isFriend(account);
|
||||
fetchResult.setData(userInfo);
|
||||
fetchResult.setStatus(LoadStatus.Success);
|
||||
} else {
|
||||
fetchResult.setError(-1, "");
|
||||
}
|
||||
friendLiveData.postValue(fetchResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchData,onFailed:" + code);
|
||||
fetchResult.setError(code, "");
|
||||
friendLiveData.postValue(fetchResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchData,onException");
|
||||
fetchResult.setError(-1, "");
|
||||
friendLiveData.postValue(fetchResult);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isBlack(String account) {
|
||||
ALog.d(LIB_TAG, TAG, "isBlack:" + account);
|
||||
return ContactRepo.isBlackList(account);
|
||||
}
|
||||
|
||||
public boolean isFriend(String account) {
|
||||
ALog.d(LIB_TAG, TAG, "isFriend:" + account);
|
||||
return ContactRepo.isFriend(account);
|
||||
}
|
||||
|
||||
public void addBlack(String account) {
|
||||
ALog.d(LIB_TAG, TAG, "addBlack:" + account);
|
||||
ContactRepo.addBlackList(
|
||||
account,
|
||||
new FetchCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable Void param) {
|
||||
ALog.d(LIB_TAG, TAG, "addBlack,onSuccess");
|
||||
fetchData(account);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "addBlack,onFailed:" + code);
|
||||
fetchResult.setError(code, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "addBlack,onException");
|
||||
fetchResult.setError(-1, "");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void removeBlack(String account) {
|
||||
ALog.d(LIB_TAG, TAG, "removeBlack:" + account);
|
||||
ContactRepo.removeBlackList(
|
||||
account,
|
||||
new FetchCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable Void param) {
|
||||
ALog.d(LIB_TAG, TAG, "removeBlack,onSuccess");
|
||||
fetchData(account);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "removeBlack,onFailed:" + code);
|
||||
fetchResult.setError(code, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "removeBlack,onException");
|
||||
fetchResult.setError(-1, "");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void deleteFriend(String account) {
|
||||
ALog.d(LIB_TAG, TAG, "deleteFriend:" + account);
|
||||
ContactRepo.deleteFriend(
|
||||
account,
|
||||
true,
|
||||
new FetchCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable Void param) {
|
||||
ALog.d(LIB_TAG, TAG, "deleteFriend,onSuccess");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "deleteFriend,onFailed:" + code);
|
||||
fetchResult.setError(code, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "deleteFriend,onException");
|
||||
fetchResult.setError(-1, "");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addFriend(String account, FriendVerifyType type, FetchCallback<Void> callback) {
|
||||
ALog.d(LIB_TAG, TAG, "addFriend:" + account);
|
||||
if (isBlackList(account)) {
|
||||
ALog.d(LIB_TAG, TAG, "addFriend,account in blacklist:" + account);
|
||||
removeBlackList(
|
||||
account,
|
||||
new FetchCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable Void param) {
|
||||
ALog.d(LIB_TAG, TAG, "addFriend,removeBlackList onSuccess:" + account);
|
||||
ContactRepo.addFriend(account, type, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "addFriend,removeBlackList onFailed:" + code);
|
||||
callback.onFailed(code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(
|
||||
LIB_TAG, TAG, "addFriend,removeBlackList onException:" + exception.getMessage());
|
||||
callback.onException(exception);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ContactRepo.addFriend(account, type, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//验证添加好友
|
||||
public void addFriendVerifyMsg(String account, String verifymsg, boolean isVerifyMsg, FetchCallback<Void> callback) {
|
||||
if (isBlackList(account)) {
|
||||
ALog.d(LIB_TAG, TAG, "addFriend,account in blacklist:" + account);
|
||||
removeBlackList(
|
||||
account,
|
||||
new FetchCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable Void param) {
|
||||
ALog.d(LIB_TAG, TAG, "addFriend,removeBlackList onSuccess:" + account);
|
||||
setRequestAddFriends(accountId, verifymsg,isVerifyMsg, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "addFriend,removeBlackList onFailed:" + code);
|
||||
callback.onFailed(code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(
|
||||
LIB_TAG, TAG, "addFriend,removeBlackList onException:" + exception.getMessage());
|
||||
callback.onException(exception);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
setRequestAddFriends(account, verifymsg, isVerifyMsg, callback);
|
||||
}
|
||||
}
|
||||
|
||||
public void setRequestAddFriends(String accountId, String msg, boolean isVerify, FetchCallback callback) {
|
||||
NIMClient.getService(FriendService.class).addFriend(new AddFriendData(accountId, isVerify ? VerifyType.VERIFY_REQUEST : VerifyType.DIRECT_ADD, msg))
|
||||
.setCallback(new RequestCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(Void result) {
|
||||
callback.onSuccess(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
callback.onFailed(code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(Throwable exception) {
|
||||
callback.onException(exception);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isBlackList(String account) {
|
||||
return ContactRepo.isBlackList(account);
|
||||
}
|
||||
|
||||
public void removeBlackList(String account, FetchCallback<Void> callback) {
|
||||
ALog.d(LIB_TAG, TAG, "removeBlackList:" + account);
|
||||
ContactRepo.removeBlackList(account, callback);
|
||||
}
|
||||
|
||||
public void updateAlias(String account, String alias) {
|
||||
ALog.d(LIB_TAG, TAG, "updateAlias:" + account);
|
||||
ContactRepo.updateAlias(account, alias);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
super.onCleared();
|
||||
ContactObserverRepo.unregisterUserInfoObserver(userInfoObserver);
|
||||
ContactObserverRepo.unregisterFriendObserver(friendObserver);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.utils;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
|
||||
public class ColorUtils {
|
||||
|
||||
public static int avatarColor(String content) {
|
||||
if (!TextUtils.isEmpty(content)) {
|
||||
return content.charAt(content.length() - 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int avatarColor(long value) {
|
||||
return (int) value % Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
public static void loadAvator(String headUrl, ContactAvatarView contactAvatarView) {
|
||||
if (TextUtils.isEmpty(headUrl)) {
|
||||
contactAvatarView.setData(R.mipmap.default_head_img, "", 0);
|
||||
} else {
|
||||
contactAvatarView.setData(headUrl, "");
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadGroupAvator(String headUrl, ContactAvatarView contactAvatarView) {
|
||||
if (TextUtils.isEmpty(headUrl)) {
|
||||
contactAvatarView.setData(R.mipmap.ic_group_defaulthead, "", 0);
|
||||
} else {
|
||||
contactAvatarView.setData(headUrl, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.netease.yunxin.kit.contactkit.ui.utils;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* json解析工具类 其实对于数组解析有一些问题
|
||||
* @author
|
||||
*/
|
||||
public class GsonUtils {
|
||||
|
||||
public static Gson gson = new Gson();
|
||||
|
||||
/**
|
||||
* 返回List对象
|
||||
* @param str
|
||||
* @param type new TypeToken<ArrayList<T>>(){}.getType()
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> T getListFromJSON(String str, Type type) {
|
||||
if (!TextUtils.isEmpty(str)) {
|
||||
return gson.fromJson(str, type);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回List对象
|
||||
* @param str
|
||||
* @param cls
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<T> getListFromJSON(String str, Class<T> cls)
|
||||
{
|
||||
Type type = new TypeToken<ArrayList<JsonObject>>()
|
||||
{}.getType();
|
||||
ArrayList<JsonObject> jsonObjects = gson.fromJson(str, type);
|
||||
ArrayList<T> arrayList = new ArrayList<>();
|
||||
for (JsonObject jsonObject : jsonObjects)
|
||||
{
|
||||
arrayList.add(gson.fromJson(jsonObject, cls));
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回对象
|
||||
* @param str
|
||||
* @param cls
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> T getObjFromJSON(String str, Class<T> cls) {
|
||||
try {
|
||||
if (!TextUtils.isEmpty(str)) {
|
||||
// LogUtils.i("参数:"+str);
|
||||
return gson.fromJson(str, cls);
|
||||
}
|
||||
return null;
|
||||
}catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回JsonString
|
||||
* @return
|
||||
*/
|
||||
public static String beanToJSONString(Object bean) {
|
||||
return new Gson().toJson(bean);
|
||||
}
|
||||
|
||||
|
||||
public static String JSONTokener(String in) {
|
||||
// consume an optional byte order mark (BOM) if it exists
|
||||
if (in != null && in.startsWith("\ufeff")) {
|
||||
in = in.substring(1);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.verify;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.FetchResult;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.LoadStatus;
|
||||
import com.netease.yunxin.kit.contactkit.ui.ILoadListener;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.activity.BaseListActivity;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.BaseListActivityLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactVerifyInfoBean;
|
||||
import com.netease.yunxin.kit.corekit.im.model.SystemMessageInfoType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BaseVerifyListActivity extends BaseListActivity implements ILoadListener {
|
||||
|
||||
protected VerifyViewModel viewModel;
|
||||
protected boolean hasInit = false;
|
||||
protected int seriesPageCount = 0;
|
||||
protected final int seriesPageLimit = 20;
|
||||
protected final int error_duplicate = 509;
|
||||
protected final int error_teamdismiss = 803;
|
||||
protected final int error_joinedteam = 809; //已经在群内
|
||||
|
||||
protected void configViewHolderFactory() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initView() {
|
||||
configTitle(binding);
|
||||
configViewHolderFactory();
|
||||
binding.contactListView.setLoadMoreListener(this);
|
||||
}
|
||||
|
||||
protected void configTitle(BaseListActivityLayoutBinding binding) {
|
||||
binding
|
||||
.title
|
||||
.setTitle(R.string.verify_msg);
|
||||
// .setActionText(R.string.clear_all)
|
||||
// .setActionListener(v -> viewModel.clearNotify());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
updateView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
viewModel.resetUnreadCount();
|
||||
binding.contactListView.getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initData() {
|
||||
viewModel = new ViewModelProvider(this).get(VerifyViewModel.class);
|
||||
viewModel
|
||||
.getFetchResult()
|
||||
.observe(
|
||||
this,
|
||||
result -> {
|
||||
if (result.getLoadStatus() == LoadStatus.Success) {
|
||||
binding.contactListView.addContactData(result.getData());
|
||||
if (result.getData() == null
|
||||
|| (result.getData() != null && result.getData().size() < 10)) {
|
||||
if (viewModel.hasMore() && seriesPageCount < seriesPageLimit) {
|
||||
seriesPageCount += result.getData() != null ? result.getData().size() : 0;
|
||||
viewModel.fetchVerifyList(true);
|
||||
}
|
||||
seriesPageCount = 0;
|
||||
}
|
||||
seriesPageCount = 0;
|
||||
|
||||
} else if (result.getLoadStatus() == LoadStatus.Finish) {
|
||||
if (result.getType() == FetchResult.FetchType.Remove) {
|
||||
binding.contactListView.removeContactData(result.getData());
|
||||
} else if (result.getType() == FetchResult.FetchType.Add) {
|
||||
addNotifyData(result.getData());
|
||||
} else if (result.getType() == FetchResult.FetchType.Update) {
|
||||
for (ContactVerifyInfoBean bean : result.getData()) {
|
||||
binding.contactListView.updateContactDataAndSort(bean);
|
||||
}
|
||||
}
|
||||
}
|
||||
hasInit = true;
|
||||
updateView();
|
||||
});
|
||||
|
||||
viewModel.fetchVerifyList(false);
|
||||
}
|
||||
|
||||
protected void updateView() {
|
||||
if (binding.contactListView.getItemCount() > 0 || !hasInit) {
|
||||
binding.contactListView.configEmptyViewRes(getEmptyStateViewRes());
|
||||
binding.contactListView.setEmptyViewVisible(View.GONE, null);
|
||||
} else {
|
||||
binding.contactListView.setEmptyViewVisible(
|
||||
View.VISIBLE, getString(R.string.verify_empty_text));
|
||||
}
|
||||
}
|
||||
|
||||
protected int getEmptyStateViewRes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected void toastResult(boolean agree, SystemMessageInfoType type, int errorCode) {
|
||||
String content = null;
|
||||
if (errorCode == error_duplicate) {
|
||||
content = getResources().getString(R.string.verify_duplicate_fail);
|
||||
} else if (type == SystemMessageInfoType.AddFriend) {
|
||||
content =
|
||||
agree
|
||||
? getResources().getString(R.string.agree_add_friend_fail)
|
||||
: getResources().getString(R.string.disagree_add_friend_fail);
|
||||
} else if ((type == SystemMessageInfoType.ApplyJoinTeam)) {
|
||||
content =
|
||||
agree
|
||||
? getResources().getString(R.string.agree_apply_join_team_fail)
|
||||
: getResources().getString(R.string.disagree_apply_join_team_fail);
|
||||
} else if ((type == SystemMessageInfoType.TeamInvite)) {
|
||||
content =
|
||||
agree
|
||||
? getResources().getString(R.string.agree_invite_team_fail)
|
||||
: getResources().getString(R.string.disagree_invite_team_fail);
|
||||
}
|
||||
Toast.makeText(this, content, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
protected void addNotifyData(List<ContactVerifyInfoBean> addList) {
|
||||
if (addList == null || addList.size() < 1) {
|
||||
return;
|
||||
}
|
||||
binding.contactListView.addForwardContactData(addList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMore() {
|
||||
return viewModel.hasMore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMore(Object last) {
|
||||
viewModel.fetchVerifyList(true);
|
||||
}
|
||||
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if(null != this.getCurrentFocus()){
|
||||
/**
|
||||
* 点击空白位置 隐藏软键盘
|
||||
*/
|
||||
InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
|
||||
return mInputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
|
||||
}
|
||||
return super .onTouchEvent(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.verify;
|
||||
|
||||
import static com.netease.yunxin.kit.contactkit.ui.ContactConstant.LIB_TAG;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import com.netease.yunxin.kit.alog.ALog;
|
||||
import com.netease.yunxin.kit.chatkit.repo.ContactObserverRepo;
|
||||
import com.netease.yunxin.kit.chatkit.repo.ContactRepo;
|
||||
import com.netease.yunxin.kit.chatkit.repo.TeamRepo;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.BaseViewModel;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.FetchResult;
|
||||
import com.netease.yunxin.kit.common.ui.viewmodel.LoadStatus;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactVerifyInfoBean;
|
||||
import com.netease.yunxin.kit.corekit.im.model.SystemMessageInfo;
|
||||
import com.netease.yunxin.kit.corekit.im.model.SystemMessageInfoStatus;
|
||||
import com.netease.yunxin.kit.corekit.im.model.SystemMessageInfoType;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.FetchCallback;
|
||||
import com.netease.yunxin.kit.corekit.im.provider.SystemMessageInfoObserver;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class VerifyViewModel extends BaseViewModel {
|
||||
|
||||
private final String TAG = "VerifyViewModel";
|
||||
private final int PAGE_LIMIT = 100;
|
||||
//7 day expire time
|
||||
private final long expireLimit = 604800000;
|
||||
private int index = 0;
|
||||
private boolean hasMore = true;
|
||||
private final MutableLiveData<FetchResult<List<ContactVerifyInfoBean>>> resultLiveData =
|
||||
new MutableLiveData<>();
|
||||
private final FetchResult<List<ContactVerifyInfoBean>> fetchResult =
|
||||
new FetchResult<>(LoadStatus.Finish);
|
||||
private final List<ContactVerifyInfoBean> verifyBeanList = new ArrayList<>();
|
||||
private final List<ContactVerifyInfoBean> updateList = new ArrayList<>();
|
||||
private final SystemMessageInfoObserver infoObserver;
|
||||
|
||||
public MutableLiveData<FetchResult<List<ContactVerifyInfoBean>>> getFetchResult() {
|
||||
return resultLiveData;
|
||||
}
|
||||
|
||||
public VerifyViewModel() {
|
||||
infoObserver =
|
||||
info -> {
|
||||
if (info.getId() > 0) {
|
||||
List<SystemMessageInfo> msgInfo = new ArrayList<>();
|
||||
msgInfo.add(info);
|
||||
ContactRepo.fillNotificationWithUserAndTeam(
|
||||
msgInfo,
|
||||
new FetchCallback<List<SystemMessageInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable List<SystemMessageInfo> param) {
|
||||
ALog.d(
|
||||
LIB_TAG,
|
||||
TAG,
|
||||
"infoObserver,onSuccess:" + (param == null ? "null" : param.size()));
|
||||
List<ContactVerifyInfoBean> add = new ArrayList<>();
|
||||
if (param != null && !param.isEmpty()) {
|
||||
resetMessageStatus(param);
|
||||
add = mergeSystemMessageList(param);
|
||||
// 如果有新的消息合并,需要更新原有消息
|
||||
if (updateList.size() > 0) {
|
||||
List<ContactVerifyInfoBean> update = new ArrayList<>(updateList);
|
||||
updateList.clear();
|
||||
fetchResult.setData(update);
|
||||
fetchResult.setFetchType(FetchResult.FetchType.Update);
|
||||
resultLiveData.setValue(fetchResult);
|
||||
}
|
||||
}
|
||||
//update
|
||||
if (add.size() > 0) {
|
||||
fetchResult.setData(add);
|
||||
fetchResult.setFetchType(FetchResult.FetchType.Add);
|
||||
resultLiveData.setValue(fetchResult);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "infoObserver,onFailed:" + code);
|
||||
fetchResult.setError(code, "");
|
||||
resultLiveData.setValue(fetchResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "infoObserver,onException");
|
||||
fetchResult.setError(-1, "");
|
||||
resultLiveData.setValue(fetchResult);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
ContactObserverRepo.registerNotificationObserver(infoObserver);
|
||||
}
|
||||
|
||||
public void fetchVerifyList(boolean nextPage) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchVerifyList,nextPage:" + nextPage);
|
||||
fetchResult.setStatus(LoadStatus.Loading);
|
||||
resultLiveData.postValue(fetchResult);
|
||||
if (nextPage) {
|
||||
if (!hasMore) {
|
||||
return;
|
||||
}
|
||||
index += PAGE_LIMIT;
|
||||
} else {
|
||||
index = 0;
|
||||
}
|
||||
ContactRepo.getNotificationList(
|
||||
index,
|
||||
PAGE_LIMIT,
|
||||
new FetchCallback<List<SystemMessageInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable List<SystemMessageInfo> param) {
|
||||
ALog.d(
|
||||
LIB_TAG,
|
||||
TAG,
|
||||
"fetchVerifyList,onSuccess:" + (param == null ? "null" : param.size()));
|
||||
fetchResult.setStatus(LoadStatus.Success);
|
||||
hasMore = (param != null && param.size() == PAGE_LIMIT);
|
||||
if (param != null && param.size() > 0) {
|
||||
resetMessageStatus(param);
|
||||
List<ContactVerifyInfoBean> add = mergeSystemMessageList(param);
|
||||
fetchResult.setData(add);
|
||||
} else {
|
||||
fetchResult.setData(null);
|
||||
}
|
||||
resultLiveData.setValue(fetchResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchVerifyList,onFailed:" + code);
|
||||
fetchResult.setError(code, "");
|
||||
resultLiveData.setValue(fetchResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(@Nullable Throwable exception) {
|
||||
ALog.d(LIB_TAG, TAG, "fetchVerifyList,onException");
|
||||
fetchResult.setError(-1, "");
|
||||
resultLiveData.setValue(fetchResult);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean hasMore() {
|
||||
return hasMore;
|
||||
}
|
||||
|
||||
public void clearNotify() {
|
||||
ALog.d(LIB_TAG, TAG, "clearNotify");
|
||||
ContactRepo.clearNotification();
|
||||
fetchResult.setFetchType(FetchResult.FetchType.Remove);
|
||||
fetchResult.setData(new ArrayList<>(verifyBeanList));
|
||||
verifyBeanList.clear();
|
||||
resultLiveData.setValue(fetchResult);
|
||||
}
|
||||
|
||||
public void agree(ContactVerifyInfoBean bean, FetchCallback<Void> callback) {
|
||||
ALog.d(LIB_TAG, TAG, "agree:" + (bean == null ? "null" : bean.data.getId()));
|
||||
SystemMessageInfo info = bean.data;
|
||||
SystemMessageInfoType type = info.getInfoType();
|
||||
SystemMessageInfoStatus status = info.getInfoStatus();
|
||||
String account = info.getFromAccount();
|
||||
if (status == SystemMessageInfoStatus.Init && !TextUtils.isEmpty(account)) {
|
||||
if (type == SystemMessageInfoType.AddFriend) {
|
||||
ContactRepo.acceptAddFriend(account, true, callback);
|
||||
} else if (type == SystemMessageInfoType.ApplyJoinTeam) {
|
||||
TeamRepo.agreeTeamApply(info.getTargetId(), account, callback);
|
||||
} else if (type == SystemMessageInfoType.TeamInvite) {
|
||||
TeamRepo.acceptTeamInvite(info.getTargetId(), account, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void disagree(ContactVerifyInfoBean bean, FetchCallback<Void> callback) {
|
||||
ALog.d(LIB_TAG, TAG, "disagree:" + (bean == null ? "null" : bean.data.getId()));
|
||||
if (bean == null || bean.data == null) {
|
||||
return;
|
||||
}
|
||||
SystemMessageInfo info = bean.data;
|
||||
SystemMessageInfoType type = info.getInfoType();
|
||||
SystemMessageInfoStatus status = info.getInfoStatus();
|
||||
String account = info.getFromAccount();
|
||||
if (status == SystemMessageInfoStatus.Init && !TextUtils.isEmpty(account)) {
|
||||
if (type == SystemMessageInfoType.AddFriend) {
|
||||
ContactRepo.acceptAddFriend(info.getFromAccount(), false, callback);
|
||||
|
||||
} else if (type == SystemMessageInfoType.ApplyJoinTeam
|
||||
&& !TextUtils.isEmpty(info.getTargetId())) {
|
||||
TeamRepo.rejectTeamApply(info.getTargetId(), account, "", callback);
|
||||
|
||||
} else if (type == SystemMessageInfoType.TeamInvite
|
||||
&& !TextUtils.isEmpty(info.getTargetId())) {
|
||||
TeamRepo.rejectTeamInvite(info.getTargetId(), account, "", callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setVerifyStatus(ContactVerifyInfoBean bean, SystemMessageInfoStatus status) {
|
||||
if (bean == null || status == null) {
|
||||
return;
|
||||
}
|
||||
ALog.d(LIB_TAG, TAG, "setVerifyStatus:" + (status == null ? "null" : status.name()));
|
||||
for (SystemMessageInfo messageInfo : bean.messageList) {
|
||||
ContactRepo.setNotificationStatus(messageInfo.getId(), status);
|
||||
}
|
||||
bean.updateStatus(status);
|
||||
}
|
||||
|
||||
public void resetUnreadCount() {
|
||||
ALog.d(LIB_TAG, TAG, "resetUnreadCount");
|
||||
ContactRepo.clearNotificationUnreadCount();
|
||||
for (ContactVerifyInfoBean verifyInfoBean : verifyBeanList) {
|
||||
verifyInfoBean.clearUnreadCount();
|
||||
}
|
||||
}
|
||||
|
||||
public void getUnreadCount(FetchCallback<Integer> callback){
|
||||
ContactRepo.getNotificationUnreadCount(callback);
|
||||
}
|
||||
|
||||
private void resetMessageStatus(List<SystemMessageInfo> infoList) {
|
||||
ALog.d(LIB_TAG, TAG, "resetMessageStatus:" + (infoList == null ? "null" : infoList.size()));
|
||||
if (infoList != null && infoList.size() > 0) {
|
||||
long lastTime = System.currentTimeMillis() - expireLimit;
|
||||
for (SystemMessageInfo info : infoList) {
|
||||
if (info.getInfoStatus() == SystemMessageInfoStatus.Init && info.getTime() < lastTime) {
|
||||
info.setInfoStatus(SystemMessageInfoStatus.Expired);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<ContactVerifyInfoBean> mergeSystemMessageList(List<SystemMessageInfo> infoList) {
|
||||
List<ContactVerifyInfoBean> add = new ArrayList<>();
|
||||
updateList.clear();
|
||||
if (infoList != null) {
|
||||
for (int index = 0; index < infoList.size(); index++) {
|
||||
boolean hasInsert = false;
|
||||
for (ContactVerifyInfoBean bean : verifyBeanList) {
|
||||
if (bean.pushMessageIfSame(infoList.get(index))) {
|
||||
hasInsert = true;
|
||||
updateList.add(bean);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasInsert) {
|
||||
ContactVerifyInfoBean infoBean = new ContactVerifyInfoBean(infoList.get(index));
|
||||
verifyBeanList.add(infoBean);
|
||||
add.add(infoBean);
|
||||
}
|
||||
}
|
||||
}
|
||||
return add;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
super.onCleared();
|
||||
ContactObserverRepo.unregisterNotificationObserver(infoObserver);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.netease.yunxin.kit.common.utils.NetworkUtils;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.UserInfoLayoutBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactUserInfoBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.utils.ColorUtils;
|
||||
|
||||
public class ContactInfoView extends FrameLayout {
|
||||
|
||||
private UserInfoLayoutBinding binding;
|
||||
|
||||
private IUserCallback userCallback;
|
||||
|
||||
public ContactInfoView(@NonNull Context context) {
|
||||
super(context);
|
||||
init(null);
|
||||
}
|
||||
|
||||
public ContactInfoView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(attrs);
|
||||
}
|
||||
|
||||
public ContactInfoView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(attrs);
|
||||
}
|
||||
|
||||
private void init(AttributeSet attrs) {
|
||||
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
|
||||
binding = UserInfoLayoutBinding.inflate(layoutInflater, this, true);
|
||||
}
|
||||
|
||||
public void setUserCallback(IUserCallback userCallback) {
|
||||
this.userCallback = userCallback;
|
||||
}
|
||||
|
||||
public void setData(ContactUserInfoBean userInfo) {
|
||||
String name = userInfo.data.getUserInfoName();
|
||||
String nickName = null;
|
||||
if (userInfo.friendInfo != null) {
|
||||
nickName = userInfo.friendInfo.getAlias();
|
||||
}
|
||||
Log.i("LAILIAOLIAO","LAILIAOLIAO用户信息:"+userInfo.data.getAvatar());
|
||||
//avatar
|
||||
binding.avatarView.setData(
|
||||
userInfo.data.getAvatar(), name, ColorUtils.avatarColor(userInfo.data.getAccount()));
|
||||
|
||||
//name
|
||||
if (TextUtils.isEmpty(nickName)) {
|
||||
binding.tvName.setText(name);
|
||||
binding.tvAccount.setText(
|
||||
String.format(
|
||||
getContext().getString(R.string.contact_user_info_account),
|
||||
userInfo.data.getAccount()));
|
||||
binding.tvCommentName.setVisibility(GONE);
|
||||
} else {
|
||||
binding.tvName.setText(nickName);
|
||||
binding.tvAccount.setText(
|
||||
String.format(getContext().getString(R.string.contact_user_info_nickname), name));
|
||||
binding.tvCommentName.setText(
|
||||
String.format(
|
||||
getContext().getString(R.string.contact_user_info_account),
|
||||
userInfo.data.getAccount()));
|
||||
binding.tvCommentName.setVisibility(VISIBLE);
|
||||
}
|
||||
|
||||
binding.tvBirthday.setText(userInfo.data.getBirthday());
|
||||
binding.tvPhone.setText(userInfo.data.getMobile());
|
||||
binding.tvEmail.setText(userInfo.data.getEmail());
|
||||
binding.tvSignature.setText(userInfo.data.getSignature());
|
||||
|
||||
if (userInfo.isFriend) {
|
||||
binding.tvDelete.setText(getResources().getText(R.string.delete_friend));
|
||||
} else {
|
||||
binding.tvDelete.setText(getResources().getText(R.string.add_friend));
|
||||
}
|
||||
binding.scBlackList.setOnCheckedChangeListener(null);
|
||||
binding.scBlackList.setChecked(userInfo.isBlack);
|
||||
|
||||
binding.scBlackList.setOnCheckedChangeListener(
|
||||
(buttonView, isChecked) -> {
|
||||
if (!NetworkUtils.isConnected()) {
|
||||
Toast.makeText(getContext(), R.string.contact_network_error_tip, Toast.LENGTH_SHORT).show();
|
||||
binding.scBlackList.toggle();
|
||||
return;
|
||||
}
|
||||
if (userCallback != null) {
|
||||
userCallback.addBlackList(isChecked);
|
||||
}
|
||||
});
|
||||
setIsFriend(userInfo.isFriend);
|
||||
}
|
||||
|
||||
public void setCommentClickListener(OnClickListener onClickListener) {
|
||||
binding.rlyComment.setOnClickListener(onClickListener);
|
||||
}
|
||||
|
||||
public void setDeleteClickListener(OnClickListener clickListener) {
|
||||
binding.tvDelete.setOnClickListener(clickListener);
|
||||
}
|
||||
|
||||
private void setIsFriend(boolean isFriend) {
|
||||
if (isFriend) {
|
||||
binding.llyFriend.setVisibility(VISIBLE);
|
||||
binding.rlyComment.setVisibility(VISIBLE);
|
||||
binding.tvChat.setOnClickListener(
|
||||
v -> {
|
||||
if (userCallback != null) {
|
||||
userCallback.goChat();
|
||||
}
|
||||
});
|
||||
binding.tvChat.setText(R.string.chat);
|
||||
binding.tvDelete.setVisibility(VISIBLE);
|
||||
} else {
|
||||
binding.llyFriend.setVisibility(GONE);
|
||||
binding.rlyComment.setVisibility(GONE);
|
||||
binding.tvChat.setText(R.string.add_friend);
|
||||
binding.tvChat.setOnClickListener(
|
||||
v -> {
|
||||
if (userCallback != null) {
|
||||
userCallback.addFriend();
|
||||
}
|
||||
});
|
||||
binding.tvDelete.setVisibility(GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public void configSCBlackSwitch(int trackRes, int thumbRes) {
|
||||
binding.scBlackList.setTrackResource(trackRes);
|
||||
binding.scBlackList.setThumbResource(thumbRes);
|
||||
}
|
||||
|
||||
public void configAvatarCorner(int cornerSize) {
|
||||
binding.avatarView.setCornerRadius(cornerSize);
|
||||
}
|
||||
|
||||
public void configChatBtnColor(int color) {
|
||||
binding.tvChat.setTextColor(color);
|
||||
}
|
||||
|
||||
public void configDivideLineColor(int color) {
|
||||
binding.divideLine1.setBackgroundColor(color);
|
||||
binding.divideLine2.setBackgroundColor(color);
|
||||
binding.divideLine3.setBackgroundColor(color);
|
||||
}
|
||||
|
||||
public void configRootBgColor(int color) {
|
||||
binding.getRoot().setBackgroundColor(color);
|
||||
}
|
||||
|
||||
public void configSignatureMaxLines(int lines) {
|
||||
binding.tvSignature.setMaxLines(lines);
|
||||
}
|
||||
|
||||
public interface IUserCallback {
|
||||
void goChat();
|
||||
|
||||
void addFriend();
|
||||
|
||||
void openMessageNotify(boolean open);
|
||||
|
||||
void addBlackList(boolean add);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.netease.yunxin.kit.common.ui.widgets.TitleBarView;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.ContactViewLayoutBinding;
|
||||
|
||||
public class ContactLayout extends LinearLayout {
|
||||
|
||||
private ContactViewLayoutBinding viewBinding;
|
||||
|
||||
public ContactLayout(@NonNull Context context) {
|
||||
super(context);
|
||||
init(null);
|
||||
}
|
||||
|
||||
public ContactLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(attrs);
|
||||
}
|
||||
|
||||
public ContactLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(attrs);
|
||||
}
|
||||
|
||||
public ContactLayout(
|
||||
@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
init(attrs);
|
||||
}
|
||||
|
||||
private void init(AttributeSet attrs) {
|
||||
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
|
||||
viewBinding = ContactViewLayoutBinding.inflate(layoutInflater, this);
|
||||
}
|
||||
|
||||
public TitleBarView getTitleBar() {
|
||||
return viewBinding.contactTitleLayout;
|
||||
}
|
||||
|
||||
public LinearLayout getTopLayout() {
|
||||
return viewBinding.contactHeaderLayout;
|
||||
}
|
||||
|
||||
public FrameLayout getBodyLayout() {
|
||||
return viewBinding.contactBodyLayout;
|
||||
}
|
||||
|
||||
public ContactListView getContactListView() {
|
||||
return viewBinding.contactListview;
|
||||
}
|
||||
|
||||
public FrameLayout getBottomLayout() {
|
||||
return viewBinding.contactBottomLayout;
|
||||
}
|
||||
|
||||
public FrameLayout getBodyTopLayout() {
|
||||
return viewBinding.contactBodyTopLayout;
|
||||
}
|
||||
|
||||
public View getDivideLineForTitle() {
|
||||
return viewBinding.divideLineTopForTitle;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,502 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.view;
|
||||
|
||||
import static com.netease.yunxin.kit.contactkit.ui.ContactConstant.LIB_TAG;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.netease.nimlib.sdk.friend.model.MuteListChangedNotify;
|
||||
import com.netease.nimlib.sdk.team.model.Team;
|
||||
import com.netease.yunxin.kit.alog.ALog;
|
||||
import com.netease.yunxin.kit.contactkit.ui.IContactFactory;
|
||||
import com.netease.yunxin.kit.contactkit.ui.ILoadListener;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.databinding.ContactListViewBinding;
|
||||
import com.netease.yunxin.kit.contactkit.ui.indexbar.suspension.SuspensionDecoration;
|
||||
import com.netease.yunxin.kit.contactkit.ui.interfaces.ContactActions;
|
||||
import com.netease.yunxin.kit.contactkit.ui.interfaces.IContactDataChanged;
|
||||
import com.netease.yunxin.kit.contactkit.ui.interfaces.IContactListView;
|
||||
import com.netease.yunxin.kit.contactkit.ui.interfaces.IContactViewAttrs;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactTeamBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.adapter.ContactAdapter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* list view for show contacts info
|
||||
*/
|
||||
public class ContactListView extends FrameLayout
|
||||
implements IContactDataChanged, IContactListView, IContactViewAttrs {
|
||||
private final String TAG = "ContactListView";
|
||||
|
||||
public ContactListViewBinding binding;
|
||||
|
||||
private ContactAdapter contactAdapter;
|
||||
|
||||
private SuspensionDecoration decoration;
|
||||
|
||||
private ILoadListener loadMoreListener;
|
||||
|
||||
private ContactListViewAttrs contactListViewAttrs;
|
||||
|
||||
private final int LOAD_MORE_DIFF = 5;
|
||||
|
||||
public ContactListView(Context context) {
|
||||
super(context);
|
||||
init(null);
|
||||
}
|
||||
|
||||
public ContactListView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(attrs);
|
||||
}
|
||||
|
||||
public ContactListView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(attrs);
|
||||
}
|
||||
|
||||
private void init(AttributeSet attrs) {
|
||||
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
|
||||
binding = ContactListViewBinding.inflate(layoutInflater, this, true);
|
||||
if (contactListViewAttrs == null) {
|
||||
contactListViewAttrs = new ContactListViewAttrs();
|
||||
}
|
||||
contactListViewAttrs.parseAttrs(getContext(), attrs);
|
||||
initRecyclerView();
|
||||
}
|
||||
|
||||
private void initRecyclerView() {
|
||||
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
|
||||
contactAdapter = new ContactAdapter();
|
||||
binding.contactList.setLayoutManager(layoutManager);
|
||||
decoration = new SuspensionDecoration(getContext(), new ArrayList<>());
|
||||
if (contactListViewAttrs.getShowPinTop()) {
|
||||
binding.contactList.addItemDecoration(
|
||||
decoration.setPaddingLeft(getContext().getResources().getDimension(R.dimen.dimen_20_dp)));
|
||||
}
|
||||
binding.contactList.setAdapter(contactAdapter);
|
||||
binding.indexBar.setLayoutManager(layoutManager);
|
||||
binding.contactList.addOnScrollListener(
|
||||
new RecyclerView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
|
||||
super.onScrollStateChanged(recyclerView, newState);
|
||||
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
|
||||
int position = layoutManager.findLastVisibleItemPosition();
|
||||
if (loadMoreListener != null
|
||||
&& loadMoreListener.hasMore()
|
||||
&& contactAdapter.getItemCount() < position + LOAD_MORE_DIFF
|
||||
&& contactAdapter.getItemCount() > 0) {
|
||||
BaseContactBean last =
|
||||
contactAdapter.getDataList().get(contactAdapter.getItemCount() - 1);
|
||||
loadMoreListener.loadMore(last);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
||||
super.onScrolled(recyclerView, dx, dy);
|
||||
}
|
||||
});
|
||||
loadAttar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setViewHolderFactory(IContactFactory viewHolderFactory) {
|
||||
if (contactAdapter != null) {
|
||||
contactAdapter.setViewHolderFactory(viewHolderFactory);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setViewConfig(ContactListViewAttrs attrs) {
|
||||
contactListViewAttrs = attrs;
|
||||
loadAttar();
|
||||
}
|
||||
|
||||
private void loadAttar() {
|
||||
if (contactListViewAttrs.getShowIndexBar() != null) {
|
||||
binding.indexBar.setVisibility(contactListViewAttrs.getShowIndexBar() ? VISIBLE : GONE);
|
||||
}
|
||||
if (contactAdapter != null) {
|
||||
contactAdapter.setContactListViewAttrs(contactListViewAttrs);
|
||||
}
|
||||
if (contactListViewAttrs.getIndexTextSize() != ContactListViewAttrs.INT_NULL) {
|
||||
decoration.setTitleFontSize(contactListViewAttrs.getIndexTextSize());
|
||||
}
|
||||
if (contactListViewAttrs.getIndexTextColor() != ContactListViewAttrs.INT_NULL) {
|
||||
decoration.setColorTitleFont(contactListViewAttrs.getIndexTextColor());
|
||||
}
|
||||
if (contactListViewAttrs.getDivideLineColor() != ContactListViewAttrs.INT_NULL) {
|
||||
decoration.setColorTitleBottomLine(contactListViewAttrs.getDivideLineColor());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTitleColor(@ColorInt int color) {
|
||||
if (contactAdapter != null) {
|
||||
contactAdapter.getContactListViewAttrs().setNameTextColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showIndexBar(boolean show) {
|
||||
if (show) {
|
||||
binding.indexBar.setVisibility(VISIBLE);
|
||||
} else {
|
||||
binding.indexBar.setVisibility(GONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//是否有可选框
|
||||
@Override
|
||||
public void showSelector(boolean show) {
|
||||
if (contactAdapter != null) {
|
||||
contactAdapter.getContactListViewAttrs().setShowSelector(show);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContactAction(ContactActions contactActions) {
|
||||
if (contactAdapter != null) {
|
||||
contactAdapter.setDefaultActions(contactActions);
|
||||
}
|
||||
}
|
||||
|
||||
public void setLoadMoreListener(ILoadListener listener) {
|
||||
this.loadMoreListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContactAdapter getAdapter() {
|
||||
return contactAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFriendDataSourceChanged(List<ContactFriendBean> contactItemBeanList) {
|
||||
if (contactAdapter != null) {
|
||||
binding
|
||||
.indexBar
|
||||
.setSourceDataAlreadySorted(false)
|
||||
.setSourceData(contactItemBeanList)
|
||||
.invalidate();
|
||||
contactAdapter.updateFriendData(contactItemBeanList);
|
||||
decoration.setData(contactAdapter.getDataList());
|
||||
}
|
||||
}
|
||||
|
||||
public void scrollToPosition(int index) {
|
||||
binding.contactList.scrollToPosition(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFriendData(List<ContactFriendBean> friend) {
|
||||
if (contactAdapter != null && friend != null) {
|
||||
List<ContactFriendBean> friendList = contactAdapter.getFriendList();
|
||||
Map<String, ContactFriendBean> friendMap = new HashMap<>();
|
||||
if (friendList != null) {
|
||||
for (ContactFriendBean friendBean : friendList) {
|
||||
if (friendBean != null && friendBean.data != null) {
|
||||
friendMap.put(friendBean.data.getAccount(), friendBean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ContactFriendBean friendBean : friend) {
|
||||
if (friendBean != null && friendBean.data != null) {
|
||||
if (friendMap.containsKey(friendBean.data.getAccount())) {
|
||||
contactAdapter.getFriendList().remove(friendMap.get(friendBean.data.getAccount()));
|
||||
}
|
||||
contactAdapter.getFriendList().add(friendBean);
|
||||
}
|
||||
}
|
||||
binding
|
||||
.indexBar
|
||||
.setSourceDataAlreadySorted(false)
|
||||
.setSourceData(contactAdapter.getFriendList())
|
||||
.invalidate();
|
||||
contactAdapter.updateFriendData();
|
||||
decoration.setData(contactAdapter.getDataList());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertFrindData(int index, ContactFriendBean friend) {
|
||||
if (contactAdapter != null && friend != null) {
|
||||
List<ContactFriendBean> friendList = contactAdapter.getFriendList();
|
||||
Map<String, ContactFriendBean> friendMap = new HashMap<>();
|
||||
if (friendList != null) {
|
||||
for (ContactFriendBean friendBean : friendList) {
|
||||
if (friendBean != null && friendBean.data != null) {
|
||||
friendMap.put(friendBean.data.getAccount(), friendBean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (friend != null && friend.data != null) {
|
||||
if (friendMap.containsKey(friend.data.getAccount())) {
|
||||
contactAdapter.getFriendList().remove(friendMap.get(friend.data.getAccount()));
|
||||
}
|
||||
contactAdapter.getFriendList().add(index, friend);
|
||||
}
|
||||
// binding
|
||||
// .indexBar
|
||||
// .setSourceDataAlreadySorted(false)
|
||||
// .setSourceData(contactAdapter.getFriendList())
|
||||
// .invalidate();
|
||||
contactAdapter.updateFriendData();
|
||||
// decoration.setData(contactAdapter.getDataList());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateGroupData(ContactTeamBean teamBeans) {
|
||||
if (contactAdapter != null) {
|
||||
contactAdapter.updateGroupData(teamBeans);
|
||||
// if (teamBeans.isNeedToPinyin()) {
|
||||
// binding.indexBar.setSourceData(contactAdapter.getDataList()).invalidate();
|
||||
// }
|
||||
decoration.setData(contactAdapter.getDataList());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFriendData(List<ContactFriendBean> friend) {
|
||||
if (contactAdapter != null) {
|
||||
contactAdapter.getFriendList().removeAll(friend);
|
||||
binding
|
||||
.indexBar
|
||||
.setSourceDataAlreadySorted(false)
|
||||
.setSourceData(contactAdapter.getFriendList())
|
||||
.invalidate();
|
||||
contactAdapter.updateFriendData();
|
||||
decoration.setData(contactAdapter.getDataList());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFriendData(List<ContactFriendBean> friends) {
|
||||
if (contactAdapter != null) {
|
||||
boolean result = contactAdapter.getFriendList().removeAll(friends);
|
||||
ALog.d(LIB_TAG, TAG, "updateFriendData, contactAdapter:" + result);
|
||||
contactAdapter.getFriendList().addAll(friends);
|
||||
binding
|
||||
.indexBar
|
||||
.setSourceDataAlreadySorted(false)
|
||||
.setSourceData(contactAdapter.getFriendList())
|
||||
.invalidate();
|
||||
contactAdapter.updateFriendData();
|
||||
decoration.setData(contactAdapter.getDataList());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateContactData(BaseContactBean data) {
|
||||
if (contactAdapter != null) {
|
||||
contactAdapter.updateData(data);
|
||||
if (data.isNeedToPinyin()) {
|
||||
binding.indexBar.setSourceData(contactAdapter.getDataList()).invalidate();
|
||||
}
|
||||
decoration.setData(contactAdapter.getDataList());
|
||||
}
|
||||
}
|
||||
|
||||
public void updateContactDataAndSort(BaseContactBean data) {
|
||||
if (contactAdapter != null) {
|
||||
contactAdapter.updateDataAndSort(data);
|
||||
if (data.isNeedToPinyin()) {
|
||||
binding.indexBar.setSourceData(contactAdapter.getDataList()).invalidate();
|
||||
}
|
||||
decoration.setData(contactAdapter.getDataList());
|
||||
}
|
||||
}
|
||||
|
||||
//conversation
|
||||
// public void setConverSationData(List<ConversationBean> data) {
|
||||
// if (contactAdapter != null) {
|
||||
// adapter.setData(data);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void addConverSationData(List<ConversationBean> data) {
|
||||
// if (adapter != null) {
|
||||
// adapter.appendData(data);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void updateConverSation(List<ConversationBean> data) {
|
||||
// if (adapter != null) {
|
||||
// ALog.d(LIB_TAG, TAG, "update ConversationBean list, start");
|
||||
// adapter.update(data);
|
||||
// ALog.d(LIB_TAG, TAG, "update ConversationBean list, end");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void updateConverSation(ConversationBean data) {
|
||||
// if (adapter != null) {
|
||||
// ALog.d(LIB_TAG, TAG, "update ConversationBean, start");
|
||||
// adapter.update(data);
|
||||
// ALog.d(LIB_TAG, TAG, "update ConversationBean, end");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void updateUserInfo(List<UserInfo> data) {
|
||||
// if (adapter != null) {
|
||||
// adapter.updateUserInfo(data);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void updateFriendInfo(List<FriendInfo> data) {
|
||||
// if (contactAdapter != null) {
|
||||
// contactAdapter.updateFriendInfo(data);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void updateTeamInfo(List<Team> data) {
|
||||
// if (contactAdapter != null) {
|
||||
// adapter.updateTeamInfo(data);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void updateMuteInfo(MuteListChangedNotify changedNotify) {
|
||||
// if (contactAdapter != null) {
|
||||
// adapter.updateMuteInfo(changedNotify);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void remove(List<ConversationBean> data) {
|
||||
// if (contactAdapter != null) {
|
||||
// adapter.removeData(data);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void removeAll() {
|
||||
// if (contactAdapter != null) {
|
||||
// adapter.removeAll();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void removeConversation(String id) {
|
||||
// if (contactAdapter != null) {
|
||||
// adapter.removeData(id);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void updateAit(List<String> idList) {
|
||||
// if (contactAdapter != null) {
|
||||
// adapter.updateAit(idList);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void addStickTop(String id) {
|
||||
// if (contactAdapter != null) {
|
||||
// adapter.addStickTop(id);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void removeStickTop(String id) {
|
||||
// if (contactAdapter != null) {
|
||||
// adapter.removeStickTop(id);
|
||||
// }
|
||||
// }
|
||||
|
||||
public int getItemCount() {
|
||||
if (contactAdapter != null) {
|
||||
return contactAdapter.getItemCount();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateContactData(int viewType, List<? extends BaseContactBean> data) {
|
||||
if (contactAdapter != null) {
|
||||
contactAdapter.updateData(viewType, data);
|
||||
decoration.setData(contactAdapter.getDataList());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addContactData(BaseContactBean contactData) {
|
||||
if (contactAdapter != null) {
|
||||
contactAdapter.addData(contactData);
|
||||
decoration.setData(contactAdapter.getDataList());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addContactData(List<? extends BaseContactBean> contactData) {
|
||||
if (contactAdapter != null) {
|
||||
contactAdapter.addListData(contactData);
|
||||
decoration.setData(contactAdapter.getDataList());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void addForwardContactData(List<? extends BaseContactBean> contactData) {
|
||||
if (contactAdapter != null) {
|
||||
contactAdapter.addForwardListData(contactData);
|
||||
decoration.setData(contactAdapter.getDataList());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeContactData(BaseContactBean contactData) {
|
||||
if (contactAdapter != null) {
|
||||
contactAdapter.removeData(contactData);
|
||||
decoration.setData(contactAdapter.getDataList());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeContactData(List<? extends BaseContactBean> contactData) {
|
||||
if (contactAdapter != null) {
|
||||
contactAdapter.removeListData(contactData);
|
||||
decoration.setData(contactAdapter.getDataList());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearContactData() {
|
||||
if (contactAdapter != null) {
|
||||
contactAdapter.clearData();
|
||||
}
|
||||
}
|
||||
|
||||
public void setEmptyViewVisible(int visible, String text) {
|
||||
binding.contactEmptyView.setVisibility(visible);
|
||||
binding.contactEmptyTv.setText(text);
|
||||
}
|
||||
|
||||
public void configEmptyViewRes(int res) {
|
||||
binding.emptyStateIv.setImageResource(res);
|
||||
}
|
||||
|
||||
public void configIndexTextBGColor(int color) {
|
||||
binding.indexBar.configIndexTextBGColor(color);
|
||||
}
|
||||
|
||||
public SuspensionDecoration getDecoration() {
|
||||
return decoration;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
|
||||
/**
|
||||
* attrs for {@link ContactListView} all attrs should be object
|
||||
*/
|
||||
public class ContactListViewAttrs {
|
||||
|
||||
public static final int INT_NULL = -1;
|
||||
|
||||
private int nameTextColor = INT_NULL;
|
||||
|
||||
private int nameTextSize = INT_NULL;
|
||||
|
||||
private int indexTextColor = INT_NULL;
|
||||
|
||||
private int indexTextSize = INT_NULL;
|
||||
|
||||
private Boolean showIndexBar;
|
||||
|
||||
private Boolean showSelector;
|
||||
|
||||
private Boolean showPinTop;
|
||||
|
||||
private float avatarCornerRadius = INT_NULL;
|
||||
|
||||
private int divideLineColor = INT_NULL;
|
||||
|
||||
public ContactListViewAttrs() {
|
||||
}
|
||||
|
||||
public void parseAttrs(Context context, AttributeSet attrs) {
|
||||
if (attrs == null) {
|
||||
return;
|
||||
}
|
||||
TypedArray t;
|
||||
t = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ContactListView, 0, 0);
|
||||
nameTextColor = t.getColor(R.styleable.ContactListView_nameTextColor, INT_NULL);
|
||||
nameTextSize = t.getDimensionPixelSize(R.styleable.ContactListView_nameTextSize, INT_NULL);
|
||||
|
||||
indexTextColor = t.getColor(R.styleable.ContactListView_indexTextColor, INT_NULL);
|
||||
indexTextSize = t.getDimensionPixelSize(R.styleable.ContactListView_indexTextSize, INT_NULL);
|
||||
|
||||
showIndexBar = t.getBoolean(R.styleable.ContactListView_showIndexBar, true);
|
||||
showPinTop = t.getBoolean(R.styleable.ContactListView_showTopPin, false);
|
||||
showSelector = t.getBoolean(R.styleable.ContactListView_showSelector, false);
|
||||
avatarCornerRadius =
|
||||
t.getDimensionPixelSize(R.styleable.ContactListView_avatarCornerRadius, INT_NULL);
|
||||
divideLineColor = t.getColor(R.styleable.ContactListView_divideLineColor, INT_NULL);
|
||||
|
||||
t.recycle();
|
||||
}
|
||||
|
||||
public ContactListViewAttrs setAll(ContactListViewAttrs other) {
|
||||
if (other.nameTextColor != INT_NULL) {
|
||||
this.nameTextColor = other.nameTextColor;
|
||||
}
|
||||
|
||||
if (other.nameTextSize != INT_NULL) {
|
||||
this.nameTextSize = other.nameTextSize;
|
||||
}
|
||||
|
||||
if (other.indexTextColor != INT_NULL) {
|
||||
this.indexTextColor = other.indexTextColor;
|
||||
}
|
||||
|
||||
if (other.indexTextSize != INT_NULL) {
|
||||
this.indexTextSize = other.indexTextSize;
|
||||
}
|
||||
|
||||
if (other.avatarCornerRadius != INT_NULL) {
|
||||
this.avatarCornerRadius = other.avatarCornerRadius;
|
||||
}
|
||||
|
||||
if (other.showIndexBar != null) {
|
||||
this.showIndexBar = other.showIndexBar;
|
||||
}
|
||||
|
||||
if (other.showSelector != null) {
|
||||
this.showSelector = other.showSelector;
|
||||
}
|
||||
|
||||
if (other.showPinTop != null) {
|
||||
this.showPinTop = other.showPinTop;
|
||||
}
|
||||
|
||||
if (other.divideLineColor != INT_NULL) {
|
||||
this.divideLineColor = other.divideLineColor;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setNameTextColor(@ColorInt int nameTextColor) {
|
||||
this.nameTextColor = nameTextColor;
|
||||
}
|
||||
|
||||
public int getNameTextColor() {
|
||||
return nameTextColor;
|
||||
}
|
||||
|
||||
public void setNameTextSize(int textSize) {
|
||||
this.nameTextSize = textSize;
|
||||
}
|
||||
|
||||
public int getNameTextSize() {
|
||||
return nameTextSize;
|
||||
}
|
||||
|
||||
public void setIndexTextSize(int textSize) {
|
||||
this.indexTextSize = textSize;
|
||||
}
|
||||
|
||||
public int getIndexTextSize() {
|
||||
return indexTextSize;
|
||||
}
|
||||
|
||||
public void setIndexTextColor(@ColorInt int color) {
|
||||
this.indexTextColor = color;
|
||||
}
|
||||
|
||||
public int getIndexTextColor() {
|
||||
return indexTextColor;
|
||||
}
|
||||
|
||||
public Boolean getShowIndexBar() {
|
||||
return showIndexBar;
|
||||
}
|
||||
|
||||
public Boolean getShowPinTop() {
|
||||
return showPinTop;
|
||||
}
|
||||
|
||||
public void setShowPinTop(Boolean showPinTop) {
|
||||
this.showPinTop = showPinTop;
|
||||
}
|
||||
|
||||
public void setShowIndexBar(Boolean showIndexBar) {
|
||||
this.showIndexBar = showIndexBar;
|
||||
}
|
||||
|
||||
public Boolean getShowSelector() {
|
||||
return showSelector;
|
||||
}
|
||||
|
||||
public void setShowSelector(Boolean showSelector) {
|
||||
this.showSelector = showSelector;
|
||||
}
|
||||
|
||||
public void setAvatarCornerRadius(float radius) {
|
||||
this.avatarCornerRadius = radius;
|
||||
}
|
||||
|
||||
public float getAvatarCornerRadius() {
|
||||
return this.avatarCornerRadius;
|
||||
}
|
||||
|
||||
public void setDivideLineColor(@ColorInt int color) {
|
||||
this.divideLineColor = color;
|
||||
}
|
||||
|
||||
public int getDivideLineColor() {
|
||||
return divideLineColor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,319 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.view.adapter;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.netease.yunxin.kit.chatkit.model.ConversationInfo;
|
||||
import com.netease.yunxin.kit.contactkit.ui.IContactFactory;
|
||||
import com.netease.yunxin.kit.contactkit.ui.R;
|
||||
import com.netease.yunxin.kit.contactkit.ui.interfaces.ContactActions;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactFriendBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.ContactTeamBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.IViewTypeConstant;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListViewAttrs;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.viewholder.BaseContactViewHolder;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class ContactAdapter extends RecyclerView.Adapter<BaseContactViewHolder> {
|
||||
|
||||
private final List<BaseContactBean> dataList;
|
||||
private final List<ContactFriendBean> friendList;
|
||||
private final List<ContactTeamBean> teamList;
|
||||
private List<ConversationInfo> conversationBeanFriendsList;
|
||||
private ContactActions defaultActions;
|
||||
|
||||
public ContactAdapter() {
|
||||
dataList = new ArrayList<>();
|
||||
friendList = new LinkedList<>();
|
||||
teamList = new LinkedList<>();
|
||||
conversationBeanFriendsList = new ArrayList<>();
|
||||
contactListViewAttrs = new ContactListViewAttrs();
|
||||
}
|
||||
|
||||
private IContactFactory viewHolderFactory;
|
||||
|
||||
private final ContactListViewAttrs contactListViewAttrs;
|
||||
|
||||
private boolean isAll = true; //默认全部展开
|
||||
|
||||
|
||||
public void setAll(boolean all) {
|
||||
isAll = all;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public BaseContactViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view =
|
||||
LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.contact_list_item_container_layout, parent, false);
|
||||
BaseContactViewHolder viewHolder =
|
||||
viewHolderFactory.createViewHolder((ViewGroup) view, viewType);
|
||||
viewHolder.setActions(defaultActions);
|
||||
return viewHolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull BaseContactViewHolder holder, int position) {
|
||||
BaseContactBean bean = dataList.get(position);
|
||||
holder.onBind(bean, position, contactListViewAttrs);
|
||||
}
|
||||
|
||||
// 通讯录调用,添加,更新,删除 好友列表
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
public void updateFriendData(List<ContactFriendBean> list) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 以前调用 removeAll 操作,数量级为 mn,
|
||||
// 由于此处目的为了移除当前所有的好友数据,直接过滤源单列表,数量级缩减为 m
|
||||
Iterator<BaseContactBean> iterator = dataList.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
BaseContactBean item = iterator.next();
|
||||
if (item.viewType == IViewTypeConstant.CONTACT_FRIEND) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
friendList.clear();
|
||||
friendList.addAll(list);
|
||||
dataList.addAll(list);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
// 通讯录调用,添加,删除,更新 好友
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
public void updateFriendData() {
|
||||
int indexStart = 0;
|
||||
if (!dataList.isEmpty()) {
|
||||
while (dataList.size() > indexStart
|
||||
&& dataList.get(indexStart) != null
|
||||
&& !(dataList.get(indexStart) instanceof ContactFriendBean)) {
|
||||
indexStart++;
|
||||
}
|
||||
while (indexStart < dataList.size()) {
|
||||
dataList.remove(indexStart);
|
||||
}
|
||||
}
|
||||
dataList.addAll(friendList);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
// 黑名单调用
|
||||
public void removeData(BaseContactBean data) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
int index = dataList.indexOf(data);
|
||||
if (index >= 0) {
|
||||
dataList.remove(data);
|
||||
notifyItemRemoved(index);
|
||||
}
|
||||
}
|
||||
|
||||
// 黑名单和验证消息列表调用
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
public void removeListData(List<? extends BaseContactBean> listData) {
|
||||
if (listData == null || listData.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (dataList.removeAll(listData)) {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// 群列表调用
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
public void clearData() {
|
||||
if (!dataList.isEmpty()) {
|
||||
dataList.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// 暂未调用
|
||||
public void clearFriendData() {
|
||||
if (!friendList.isEmpty()) {
|
||||
friendList.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// 通讯录调用,用于添加头部
|
||||
public void addData(BaseContactBean data) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
if (!dataList.isEmpty() && data.weight > 0) {
|
||||
int index = 0;
|
||||
while (dataList.size() > index
|
||||
&& dataList.get(index) != null
|
||||
&& dataList.get(index).weight >= data.weight) {
|
||||
index++;
|
||||
}
|
||||
dataList.add(index, data);
|
||||
notifyItemInserted(index);
|
||||
} else {
|
||||
dataList.add(data);
|
||||
notifyItemInserted(dataList.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// 验证,好友选择,通讯录调用
|
||||
public void updateData(BaseContactBean data) {
|
||||
int index = dataList.indexOf(data);
|
||||
if (index >= 0) {
|
||||
dataList.set(index, data);
|
||||
notifyItemChanged(index);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新群聊
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
public void updateGroupData(ContactTeamBean itembean) {
|
||||
if (itembean == null) {
|
||||
return;
|
||||
}
|
||||
for (BaseContactBean baseContactBean : dataList) {
|
||||
if (baseContactBean instanceof ContactTeamBean) {
|
||||
if (((ContactTeamBean) baseContactBean).data.getId().equals(itembean.data.getId())) {
|
||||
dataList.remove(baseContactBean);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dataList.add(0, itembean);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
// 验证,好友选择,通讯录调用
|
||||
public void updateDataAndSort(BaseContactBean data) {
|
||||
int index = dataList.indexOf(data);
|
||||
if (index >= 0) {
|
||||
dataList.remove(index);
|
||||
notifyItemRemoved(index);
|
||||
dataList.add(0, data);
|
||||
notifyItemInserted(0);
|
||||
}
|
||||
}
|
||||
|
||||
// 暂未调用
|
||||
public void updateData(int viewType, List<? extends BaseContactBean> list) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int indexStart = 0;
|
||||
int indexEnd;
|
||||
if (!dataList.isEmpty()) {
|
||||
while (dataList.size() > indexStart
|
||||
&& dataList.get(indexStart) != null
|
||||
&& dataList.get(indexStart).viewType != viewType) {
|
||||
indexStart++;
|
||||
}
|
||||
indexEnd = indexStart;
|
||||
while (dataList.size() > indexEnd
|
||||
&& dataList.get(indexEnd) != null
|
||||
&& dataList.get(indexEnd).viewType == viewType) {
|
||||
indexEnd++;
|
||||
}
|
||||
if (indexEnd < dataList.size()) {
|
||||
List<BaseContactBean> temp = dataList.subList(indexStart, indexEnd);
|
||||
dataList.removeAll(temp);
|
||||
}
|
||||
}
|
||||
dataList.addAll(list);
|
||||
indexEnd = indexStart + list.size();
|
||||
notifyItemRangeChanged(indexStart, indexEnd);
|
||||
}
|
||||
|
||||
// 用户配置,通讯录添加列表头部信息
|
||||
public void addListData(List<? extends BaseContactBean> listData) {
|
||||
if (listData == null || listData.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (listData.get(0).weight > 0) {
|
||||
int index = 0;
|
||||
while (dataList.size() > index
|
||||
&& dataList.get(index) != null
|
||||
&& dataList.get(index).weight >= listData.get(0).weight) {
|
||||
index++;
|
||||
}
|
||||
dataList.addAll(index, listData);
|
||||
notifyItemRangeInserted(index, listData.size());
|
||||
} else {
|
||||
dataList.addAll(listData);
|
||||
notifyItemRangeInserted(dataList.size() - 1, listData.size());
|
||||
}
|
||||
}
|
||||
|
||||
// 验证消息调用
|
||||
public void addForwardListData(List<? extends BaseContactBean> listData) {
|
||||
if (listData == null || listData.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
dataList.addAll(0, listData);
|
||||
notifyItemRangeInserted(0, listData.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
// if (isAll) {
|
||||
return dataList.size();
|
||||
// } else {
|
||||
// return Math.min(dataList.size(), 3);
|
||||
// }
|
||||
// return dataList.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (dataList.get(position) != null) {
|
||||
return viewHolderFactory.getItemViewType(dataList.get(position));
|
||||
}
|
||||
return super.getItemViewType(position);
|
||||
}
|
||||
|
||||
public ContactListViewAttrs getContactListViewAttrs() {
|
||||
return contactListViewAttrs;
|
||||
}
|
||||
|
||||
public void setViewHolderFactory(IContactFactory factory) {
|
||||
viewHolderFactory = factory;
|
||||
}
|
||||
|
||||
public void setDefaultActions(ContactActions actions) {
|
||||
defaultActions = actions;
|
||||
}
|
||||
|
||||
public void setContactListViewAttrs(ContactListViewAttrs attrs) {
|
||||
contactListViewAttrs.setAll(attrs);
|
||||
}
|
||||
|
||||
public List<BaseContactBean> getDataList() {
|
||||
return dataList;
|
||||
}
|
||||
|
||||
public List<ContactFriendBean> getFriendList() {
|
||||
return friendList;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui.view.viewholder;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.netease.yunxin.kit.contactkit.ui.interfaces.ContactActions;
|
||||
import com.netease.yunxin.kit.contactkit.ui.model.BaseContactBean;
|
||||
import com.netease.yunxin.kit.contactkit.ui.view.ContactListViewAttrs;
|
||||
|
||||
public abstract class BaseContactViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
protected ContactActions actions;
|
||||
|
||||
protected Context context;
|
||||
|
||||
public BaseContactViewHolder(@NonNull ViewGroup itemView) {
|
||||
super(itemView);
|
||||
context = itemView.getContext();
|
||||
LayoutInflater layoutInflater = LayoutInflater.from(context);
|
||||
initViewBinding(layoutInflater, itemView);
|
||||
}
|
||||
|
||||
public abstract void initViewBinding(LayoutInflater layoutInflater, ViewGroup container);
|
||||
|
||||
public void setActions(ContactActions actions) {
|
||||
this.actions = actions;
|
||||
}
|
||||
|
||||
public abstract void onBind(BaseContactBean bean, int position, ContactListViewAttrs attrs);
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
BIN
contactkit-ui/src/main/res-fun/drawable-xxhdpi/ic_teamqrcode.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
contactkit-ui/src/main/res-fun/drawable-xxhdpi/ic_teamurl.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 757 B |
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="6dp" />
|
||||
<solid android:color="@color/color_f4f4f4" />
|
||||
|
||||
</shape>
|
||||
14
contactkit-ui/src/main/res-fun/drawable/fun_bg_search_et.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="4dp" />
|
||||
<solid android:color="@color/fun_contact_search_edit_bg_color"/>
|
||||
|
||||
</shape>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners
|
||||
android:topLeftRadius="@dimen/dimen_12_dp"
|
||||
android:topRightRadius="@dimen/dimen_12_dp" />
|
||||
<solid android:color="@color/color_white" />
|
||||
</shape>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="@dimen/dimen_6_dp" />
|
||||
<solid android:color="@color/color_58be6b" />
|
||||
</shape>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="@dimen/dimen_4_dp" />
|
||||
<solid android:color="@color/color_white" />
|
||||
</shape>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="@dimen/dimen_12_dp" />
|
||||
<solid android:color="@color/color_fe6881" />
|
||||
</shape>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="@dimen/dimen_6_dp" />
|
||||
<solid android:color="@color/color_cccccc" />
|
||||
</shape>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<inset xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
|
||||
android:drawable="@drawable/fun_bottom_dialog_bg"
|
||||
android:insetTop="88dp">
|
||||
|
||||
</inset>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<inset xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
|
||||
android:drawable="@drawable/fun_bottom_dialog_bg"
|
||||
android:insetTop="290dp">
|
||||
|
||||
</inset>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="@dimen/dimen_20_dp" />
|
||||
|
||||
<solid
|
||||
android:color="@color/color_6877fe" />
|
||||
|
||||
</shape>
|
||||
@@ -0,0 +1,32 @@
|
||||
<!-- Copyright (c) 2022 NetEase, Inc. All rights reserved. -->
|
||||
<!-- Use of this source code is governed by a MIT license that can be -->
|
||||
<!-- found in the LICENSE file. -->
|
||||
|
||||
<!--<vector xmlns:android="http://schemas.android.com/apk/res/android"-->
|
||||
<!-- android:width="@dimen/dimen_20_dp"-->
|
||||
<!-- android:height="@dimen/dimen_20_dp"-->
|
||||
<!-- android:viewportWidth="20"-->
|
||||
<!-- android:viewportHeight="20">-->
|
||||
<!-- <path-->
|
||||
<!-- android:strokeWidth="1"-->
|
||||
<!-- android:pathData="M9,9m-8.5,0a8.5,8.5 0,1 1,17 0a8.5,8.5 0,1 1,-17 0"-->
|
||||
<!-- android:fillColor="@android:color/white"-->
|
||||
<!-- android:strokeColor="#d8d8d8" />-->
|
||||
<!--</vector>-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="@dimen/dimen_3_dp" />
|
||||
|
||||
<size
|
||||
android:width="@dimen/dimen_20_dp"
|
||||
android:height="@dimen/dimen_20_dp" />
|
||||
|
||||
<solid android:color="@android:color/white" />
|
||||
|
||||
<stroke
|
||||
android:width="@dimen/dimen_1_dp"
|
||||
android:color="@color/color_d8d8d8"/>
|
||||
|
||||
</shape>
|
||||
@@ -0,0 +1,16 @@
|
||||
<!-- Copyright (c) 2022 NetEase, Inc. All rights reserved. -->
|
||||
<!-- Use of this source code is governed by a MIT license that can be -->
|
||||
<!-- found in the LICENSE file. -->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="18dp"
|
||||
android:height="18dp"
|
||||
android:viewportWidth="18"
|
||||
android:viewportHeight="18">
|
||||
<path
|
||||
android:pathData="M9,9m-9,0a9,9 0,1 1,18 0a9,9 0,1 1,-18 0"
|
||||
android:fillColor="#58BE6B" />
|
||||
<path
|
||||
android:pathData="M5.1508,8.7407C4.7315,8.3813 4.1002,8.4299 3.7407,8.8492C3.3813,9.2685 3.4299,9.8998 3.8492,10.2593L5.1508,8.7407ZM8,12.5L7.3492,13.2593C7.7587,13.6102 8.3727,13.5733 8.7372,13.1757L8,12.5ZM14.2372,7.1757C14.6103,6.7686 14.5828,6.136 14.1757,5.7628C13.7686,5.3896 13.136,5.4172 12.7628,5.8243L14.2372,7.1757ZM3.8492,10.2593L7.3492,13.2593L8.6508,11.7407L5.1508,8.7407L3.8492,10.2593ZM8.7372,13.1757L14.2372,7.1757L12.7628,5.8243L7.2628,11.8243L8.7372,13.1757Z"
|
||||
android:fillColor="#ffffff" />
|
||||
</vector>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Copyright (c) 2022 NetEase, Inc. All rights reserved. -->
|
||||
<!-- Use of this source code is governed by a MIT license that can be -->
|
||||
<!-- found in the LICENSE file. -->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@drawable/fun_ic_selected_conversation" android:state_checked="true" />
|
||||
|
||||
<item android:drawable="@drawable/fun_ic_unselector_conversation" android:state_checked="false" />
|
||||
|
||||
</selector>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
|
||||
<corners android:radius="6dp"/>
|
||||
<solid android:color="#f4f4f4"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<size
|
||||
android:width="@dimen/dimen_20_dp"
|
||||
android:height="@dimen/dimen_20_dp" />
|
||||
|
||||
<solid android:color="@color/color_white" />
|
||||
<stroke android:width="1dp" android:color="@color/color_dbdde4"/>
|
||||
|
||||
</shape>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<size
|
||||
android:width="@dimen/dimen_20_dp"
|
||||
android:height="@dimen/dimen_20_dp" />
|
||||
|
||||
<solid android:color="@color/color_white" />
|
||||
<stroke android:width="1dp" android:color="@color/color_58be6b"/>
|
||||
|
||||
</shape>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@drawable/fun_switch_thumb_on" android:state_checked="true" />
|
||||
|
||||
<item android:drawable="@drawable/fun_switch_thumb_off" android:state_checked="false" />
|
||||
|
||||
</selector>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="@dimen/dimen_10_dp"/>
|
||||
|
||||
<size
|
||||
android:width="@dimen/dimen_60_dp"
|
||||
android:height="@dimen/dimen_20_dp" />
|
||||
|
||||
<solid android:color="@color/color_dbdde4" />
|
||||
|
||||
</shape>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="@dimen/dimen_10_dp" />
|
||||
|
||||
<size
|
||||
android:width="@dimen/dimen_60_dp"
|
||||
android:height="@dimen/dimen_20_dp" />
|
||||
|
||||
<solid android:color="@color/color_58be6b" />
|
||||
|
||||
</shape>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@drawable/fun_switch_track_on" android:state_checked="true" />
|
||||
|
||||
<item android:drawable="@drawable/fun_switch_track_off" android:state_checked="false" />
|
||||
|
||||
</selector>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="@dimen/dimen_30_dp" />
|
||||
|
||||
<solid
|
||||
android:color="@color/color_6d80ff_alpha70" />
|
||||
|
||||
</shape>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="@dimen/dimen_30_dp" />
|
||||
|
||||
<solid
|
||||
android:color="@color/color_6d80ff" />
|
||||
|
||||
</shape>
|
||||
@@ -0,0 +1,289 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<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="match_parent"
|
||||
android:background="@android:color/white">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_add_friend_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/page_title_bar_height"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="MissingConstraints">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_add_friend_back"
|
||||
android:layout_width="@dimen/image_operate_width_height"
|
||||
android:layout_height="@dimen/image_operate_width_height"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginLeft="@dimen/page_margin_left_right"
|
||||
android:src="@mipmap/ic_back" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_add_friend_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="@dimen/page_margin_left_right"
|
||||
android:layout_marginRight="@dimen/page_margin_left_right"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/search_friend_title"
|
||||
android:textColor="@android:color/black"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_add_friend_more"
|
||||
android:layout_width="@dimen/image_operate_width_height"
|
||||
android:layout_height="@dimen/image_operate_width_height"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginRight="20dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/line_searchfriend_top"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:background="@color/color_f7f7f7"
|
||||
app:layout_constraintTop_toBottomOf="@+id/layout_add_friend_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_searchfriend_id"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_15_dp"
|
||||
android:drawableStart="@drawable/ic_selected_search"
|
||||
android:drawablePadding="@dimen/dimen_10_dp"
|
||||
android:paddingTop="@dimen/dimen_30_dp"
|
||||
android:text="@string/lailiaozhanghao_txt"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/line_searchfriend_top" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_searchfriend_phone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_60_dp"
|
||||
android:drawableStart="@drawable/ic_unselected_search"
|
||||
android:drawablePadding="@dimen/dimen_10_dp"
|
||||
android:paddingTop="@dimen/dimen_30_dp"
|
||||
android:text="@string/addfriends_phone"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
app:layout_constraintLeft_toRightOf="@+id/tv_searchfriend_id"
|
||||
app:layout_constraintTop_toBottomOf="@+id/line_searchfriend_top" />
|
||||
|
||||
<!--Demo 布局-->
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_add_friend_input"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_40_dp"
|
||||
android:layout_marginLeft="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_30_dp"
|
||||
android:layout_marginRight="@dimen/dimen_15_dp"
|
||||
android:background="@drawable/fun_selected_user_bg"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_searchfriend_id"
|
||||
tools:ignore="MissingConstraints">
|
||||
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_add_friend_account"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="@dimen/dimen_15_dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@null"
|
||||
android:hint="@string/add_friend_searchid_hint"
|
||||
android:imeOptions="actionSearch"
|
||||
android:singleLine="true"
|
||||
android:textColorHint="@color/color_d4dbd6"
|
||||
android:textCursorDrawable="@null"
|
||||
android:textSize="@dimen/text_size_14" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_friendaccount_clear"
|
||||
android:layout_width="@dimen/dimen_12_dp"
|
||||
android:layout_height="@dimen/dimen_12_dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="@dimen/dimen_12_dp"
|
||||
android:layout_marginRight="@dimen/dimen_12_dp"
|
||||
android:src="@drawable/ic_clear"
|
||||
android:visibility="gone" />
|
||||
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_friendaccount_search"
|
||||
android:layout_width="@dimen/dimen_12_dp"
|
||||
android:layout_height="@dimen/dimen_12_dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="@dimen/dimen_12_dp"
|
||||
android:layout_marginRight="@dimen/dimen_15_dp"
|
||||
android:src="@mipmap/ic_search" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<!--手机号输入布局-->
|
||||
<RelativeLayout
|
||||
android:id="@+id/ly_searchfriend_inputphone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_30_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_searchfriend_id">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/area_tv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/dimen_50_dp"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingEnd="@dimen/dimen_10_dp"
|
||||
android:text=" +886"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="18sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/phone_et"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_50_dp"
|
||||
android:layout_toRightOf="@+id/area_tv"
|
||||
android:background="@null"
|
||||
android:hint="@string/add_friend_searchphone_hint"
|
||||
android:imeOptions="actionSearch"
|
||||
android:inputType="phone"
|
||||
android:paddingLeft="@dimen/dimen_20_dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textColorHint="@color/color_bcbcbc"
|
||||
android:textCursorDrawable="@null"
|
||||
android:textSize="@dimen/text_size_18" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_friend_clear"
|
||||
android:layout_width="@dimen/dimen_12_dp"
|
||||
android:layout_height="@dimen/dimen_12_dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="@dimen/dimen_30_dp"
|
||||
android:src="@drawable/ic_clear"
|
||||
android:visibility="gone" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/iv_friendphone_search"
|
||||
android:layout_width="@dimen/dimen_16_dp"
|
||||
android:layout_height="@dimen/dimen_16_dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
app:srcCompat="@mipmap/ic_search_edit" />
|
||||
|
||||
<View
|
||||
android:id="@+id/line_searchfriend_phone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:layout_below="@+id/phone_et"
|
||||
android:background="@color/color_d8d8d8" />
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_userinfo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_163_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_searchfriend_phone">
|
||||
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView
|
||||
android:id="@+id/av_indexfra_head"
|
||||
android:layout_width="@dimen/dimen_64_dp"
|
||||
android:layout_height="@dimen/dimen_64_dp"
|
||||
app:avatarCorner="@dimen/dimen_64_dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_username"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_10_dp"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_18"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/titleBarView" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_usertips"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_5_dp"
|
||||
android:textColor="@color/color_7e7b84"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintLeft_toLeftOf="parent" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_userinfohint"
|
||||
android:layout_width="@dimen/dimen_58_dp"
|
||||
android:layout_height="@dimen/dimen_32_dp"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:background="@drawable/cornor_6d94ff_20dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/add_friend_search_result"
|
||||
android:textColor="@color/color_white"
|
||||
android:textSize="@dimen/text_size_14" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/add_friend_empty_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_weight="1"
|
||||
tools:ignore="MissingConstraints">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/empty_state_iv"
|
||||
android:layout_width="@dimen/dimen_188_dp"
|
||||
android:layout_height="@dimen/verify_name_max_len"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="@dimen/dimen_70_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_16_dp"
|
||||
android:src="@drawable/fun_ic_contact_empty" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/add_friend_empty_tv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/add_friend_search_empty_tips"
|
||||
android:textColor="@color/color_b3b7bc" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/root_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView
|
||||
android:id="@+id/avatar_view"
|
||||
android:layout_width="@dimen/dimen_40_dp"
|
||||
android:layout_height="@dimen/dimen_40_dp"
|
||||
android:layout_marginTop="@dimen/dimen_12_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_12_dp"
|
||||
android:layout_marginStart="@dimen/dimen_20_dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_12_dp"
|
||||
android:textSize="@dimen/text_size_17"
|
||||
android:textColor="@color/color_14131b"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
app:layout_constrainedWidth="true"
|
||||
android:layout_marginEnd="@dimen/dimen_100_dp"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="@+id/avatar_view" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_relieve"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/title_color"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:paddingHorizontal="@dimen/dimen_16_dp"
|
||||
android:paddingVertical="@dimen/dimen_8_dp"
|
||||
android:background="@drawable/negative_btn_bg"
|
||||
android:layout_marginEnd="@dimen/dimen_20_dp"
|
||||
android:text="@string/contact_black_list_relieve"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatRadioButton
|
||||
android:id="@+id/rb_selector"
|
||||
style="@style/FunSelectorRadioBtn"
|
||||
android:layout_width="@dimen/dimen_18_dp"
|
||||
android:layout_height="@dimen/dimen_18_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:clickable="false"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:visibility="visible" />
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:visibility="gone"
|
||||
android:background="@color/color_e5e5e5"
|
||||
app:layout_constraintStart_toStartOf="@+id/avatar_view"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,146 @@
|
||||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#4D000000">
|
||||
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/fun_bottom_dialog_bg"
|
||||
app:layout_constraintBottom_toBottomOf="parent">
|
||||
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView
|
||||
android:id="@+id/cavUserIcon"
|
||||
android:layout_width="@dimen/dimen_45_dp"
|
||||
android:layout_height="@dimen/dimen_45_dp"
|
||||
android:layout_marginStart="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
app:avatarCorner="@dimen/dimen_45_dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvUserName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_15_dp"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/cavUserIcon"
|
||||
app:layout_constraintLeft_toRightOf="@+id/cavUserIcon"
|
||||
app:layout_constraintTop_toTopOf="@+id/cavUserIcon" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:background="@drawable/ic_dialog_close"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/cavUserIcon" />
|
||||
|
||||
<View
|
||||
android:id="@+id/view_closeclick"
|
||||
android:layout_width="@dimen/dimen_50_dp"
|
||||
android:layout_height="@dimen/dimen_50_dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_15_dp"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/cavUserIcon"
|
||||
app:layout_constraintLeft_toRightOf="@+id/cavUserIcon"
|
||||
app:layout_constraintTop_toTopOf="@+id/cavUserIcon" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_addfriends_verifymsg_tips"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:text="@string/fun_contact_addfriends_verifymsg"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="@+id/cavUserIcon"
|
||||
app:layout_constraintTop_toBottomOf="@+id/cavUserIcon" />
|
||||
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_addfriends_verifymsg"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/dimen_92_dp"
|
||||
android:layout_marginTop="@dimen/dimen_10_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:background="@drawable/fun_bg_addfriends_verifymsg"
|
||||
android:gravity="top"
|
||||
android:hint="@string/fun_contact_verifymsg_tips"
|
||||
android:paddingStart="@dimen/dimen_10_dp"
|
||||
android:paddingTop="@dimen/dimen_15_dp"
|
||||
android:textColorHint="@color/color_bcbcbc"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/cavUserIcon"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_addfriends_verifymsg_tips" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_addfriends_remarks_tips"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:text="@string/fun_contact_addfriends_remarks"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintStart_toStartOf="@+id/cavUserIcon"
|
||||
app:layout_constraintTop_toBottomOf="@+id/edit_addfriends_verifymsg" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_addfriends_remarkmsg"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/dimen_46_dp"
|
||||
android:layout_marginTop="@dimen/dimen_10_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:background="@drawable/fun_bg_addfriends_verifymsg"
|
||||
android:gravity="top"
|
||||
android:hint="@string/fun_contact_remarks_tips"
|
||||
android:paddingStart="@dimen/dimen_10_dp"
|
||||
android:paddingTop="@dimen/dimen_15_dp"
|
||||
android:visibility="gone"
|
||||
android:textColorHint="@color/color_bcbcbc"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/cavUserIcon"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_addfriends_remarks_tips" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_addfriends_send"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/dimen_40_dp"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_60_dp"
|
||||
android:background="@drawable/fun_cornor_12d_fe6881"
|
||||
android:gravity="center"
|
||||
android:text="@string/fun_contact_addfriends_send"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/cavUserIcon"
|
||||
app:layout_constraintTop_toBottomOf="@+id/edit_addfriends_remarkmsg" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/color_ededed"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.BackTitleBar
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.CleanableEditText
|
||||
android:id="@+id/edt_comment"
|
||||
android:layout_width="match_parent"
|
||||
android:maxLength="15"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="MissingDefaultResource">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/contact_fragment_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<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"
|
||||
android:background="@drawable/fun_bottom_dialog_bg"
|
||||
android:paddingBottom="30dp">
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTip"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="51dp"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/color_8f8f8f"
|
||||
android:textSize="13dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/tvDelete"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:ignore="SpUsage" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.5dp"
|
||||
android:background="@color/color_ededed"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvTip" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDelete"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="51dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/delete_friend"
|
||||
android:textColor="@color/color_e6605c"
|
||||
android:textSize="16dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/tvCancel"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:ignore="SpUsage" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="6dp"
|
||||
android:background="@color/color_f7f7f7"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvDelete" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCancel"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="42dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/cancel"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:ignore="SpUsage" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.netease.yunxin.kit.contactkit.ui.view.ContactLayout
|
||||
android:id="@+id/contact_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_15_dp"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/empty_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_188_dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/dimen_118_dp"
|
||||
android:layout_height="@dimen/dimen_96_dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:src="@drawable/fun_ic_contact_empty" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty_tv"
|
||||
android:layout_width="@dimen/dimen_118_dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center"
|
||||
android:text="@string/selector_friend_empty" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,191 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/layout_selectorroot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/white"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.BackTitleBar
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:background="@color/color_f7f7f7" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_40_dp"
|
||||
android:layout_marginStart="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_10_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:background="@drawable/fun_bg_addfriends_verifymsg"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_selector_friends"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0.9"
|
||||
android:background="@null"
|
||||
android:drawableStart="@drawable/fun_ic_conversation_search"
|
||||
android:drawablePadding="@dimen/dimen_5_dp"
|
||||
android:hint="@string/fun_contact_createteam_tips"
|
||||
android:imeOptions="actionSearch"
|
||||
android:paddingStart="@dimen/dimen_15_dp"
|
||||
android:singleLine="true"
|
||||
android:textColorHint="@color/color_cccccc"
|
||||
android:textCursorDrawable="@null" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/ic_clean_edit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_weight="0.1"
|
||||
android:visibility="gone"
|
||||
app:srcCompat="@drawable/ic_selector_close" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="none">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_selected"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:paddingHorizontal="@dimen/dimen_15_dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_searchlist"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:text="@string/fun_searchresult_txt"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.netease.yunxin.kit.contactkit.ui.view.ContactListView
|
||||
android:id="@+id/contact_searchlistView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_10_dp"
|
||||
app:showIndexBar="false"
|
||||
app:showSelector="true" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 最近联系 关注 全部-->
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_contactlist"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_contactlast"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:textColor="@color/color_333333"
|
||||
android:visibility="gone"
|
||||
android:textSize="@dimen/text_size_14" />
|
||||
|
||||
<com.netease.yunxin.kit.contactkit.ui.view.ContactListView
|
||||
android:id="@+id/contact_last"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
app:showIndexBar="false"
|
||||
android:visibility="gone"
|
||||
app:showSelector="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_contactspecialgz"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.netease.yunxin.kit.contactkit.ui.view.ContactListView
|
||||
android:id="@+id/contact_listView_mylove"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:visibility="gone"
|
||||
app:showIndexBar="false"
|
||||
app:showSelector="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_contactmember"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_14" />
|
||||
|
||||
<com.netease.yunxin.kit.contactkit.ui.view.ContactListView
|
||||
android:id="@+id/contact_listView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_10_dp"
|
||||
app:showIndexBar="false"
|
||||
app:showSelector="true" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/empty_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_188_dp"
|
||||
android:layout_marginTop="@dimen/dimen_150_dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/dimen_118_dp"
|
||||
android:layout_height="@dimen/dimen_96_dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:src="@drawable/fun_ic_contact_empty" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty_tv"
|
||||
android:layout_width="@dimen/dimen_118_dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center"
|
||||
android:text="@string/selector_friend_empty" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,232 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/layout_selectorroot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.BackTitleBar
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<View
|
||||
android:id="@+id/line_top"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:background="@color/color_f7f7f7" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/lly_teamsetting"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_10_dp"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_teamqr"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:drawablePadding="@dimen/dimen_10_dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/fun_contactselector_teamqr"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
app:drawableTopCompat="@drawable/ic_teamqrcode" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_teamurl"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:drawablePadding="@dimen/dimen_10_dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/fun_contactselector_teamurl"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
app:drawableTopCompat="@drawable/ic_teamurl" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:visibility="invisible" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_40_dp"
|
||||
android:layout_marginStart="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:background="@drawable/fun_bg_addfriends_verifymsg"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_selector_friends"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0.9"
|
||||
android:background="@null"
|
||||
android:drawableStart="@drawable/fun_ic_conversation_search"
|
||||
android:drawablePadding="@dimen/dimen_5_dp"
|
||||
android:hint="@string/fun_contact_createteam_tips"
|
||||
android:imeOptions="actionSearch"
|
||||
android:paddingStart="@dimen/dimen_15_dp"
|
||||
android:singleLine="true"
|
||||
android:textColorHint="@color/color_cccccc"
|
||||
android:textCursorDrawable="@null" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/ic_clean_edit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_weight="0.1"
|
||||
android:visibility="gone"
|
||||
app:srcCompat="@drawable/ic_selector_close" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="none">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_selected"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:paddingHorizontal="@dimen/dimen_15_dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_searchlist"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:text="查找结果"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.netease.yunxin.kit.contactkit.ui.view.ContactListView
|
||||
android:id="@+id/contact_searchlistView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_10_dp"
|
||||
app:showIndexBar="false"
|
||||
app:showSelector="true" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_contactlist"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_contactlast"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:visibility="gone"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.netease.yunxin.kit.contactkit.ui.view.ContactListView
|
||||
android:id="@+id/contact_last"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
app:showIndexBar="false"
|
||||
android:visibility="gone"
|
||||
app:showSelector="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_contactspecialgz"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:visibility="gone"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.netease.yunxin.kit.contactkit.ui.view.ContactListView
|
||||
android:id="@+id/contact_listView_mylove"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
app:showIndexBar="false"
|
||||
android:visibility="gone"
|
||||
app:showSelector="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_contactmember"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.netease.yunxin.kit.contactkit.ui.view.ContactListView
|
||||
android:id="@+id/contact_listView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_10_dp"
|
||||
app:showIndexBar="false"
|
||||
app:showSelector="true" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/empty_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_188_dp"
|
||||
android:layout_marginTop="@dimen/dimen_150_dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/dimen_118_dp"
|
||||
android:layout_height="@dimen/dimen_96_dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:src="@drawable/fun_ic_contact_empty" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty_tv"
|
||||
android:layout_width="@dimen/dimen_118_dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center"
|
||||
android:text="@string/selector_friend_empty" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,170 @@
|
||||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/white">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.BackTitleBar
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:rightTitleText="@string/fun_creategroup_sure"
|
||||
app:titleText="@string/fun_creategroup_title" />
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView
|
||||
android:id="@+id/ic_grouphead"
|
||||
android:layout_width="@dimen/dimen_88_dp"
|
||||
android:layout_height="@dimen/dimen_88_dp"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
app:avatarCorner="@dimen/dimen_88_dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/title" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/ic_groupheadtop"
|
||||
android:layout_width="@dimen/dimen_88_dp"
|
||||
android:layout_height="@dimen/dimen_88_dp"
|
||||
app:srcCompat="@mipmap/ic_grouphead_setting"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/ic_grouphead"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/dimen_8_dp"
|
||||
android:background="#23000000"
|
||||
android:text="@string/fun_creategroup_uploadhead"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="@dimen/text_size_12"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/ic_grouphead"
|
||||
app:layout_constraintEnd_toEndOf="@+id/ic_grouphead"
|
||||
app:layout_constraintStart_toStartOf="@+id/ic_grouphead" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvgroup_tipsname"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:text="@string/fun_creategroup_name"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/ic_grouphead" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llgroupname"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/tvgroup_tipsname"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvgroup_tipsname">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_groupname"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:layout_weight="0.9"
|
||||
android:background="@null"
|
||||
android:ellipsize="end"
|
||||
android:maxLength="20"
|
||||
android:maxLines="1"
|
||||
android:paddingLeft="@dimen/dimen_15_dp"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textColorHint="@color/color_bcbcbc"
|
||||
android:textSize="@dimen/text_size_16" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/ic_clean_edit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginEnd="@dimen/dimen_10_dp"
|
||||
android:layout_weight="0.1"
|
||||
android:paddingTop="@dimen/dimen_20_dp"
|
||||
android:visibility="gone"
|
||||
app:srcCompat="@drawable/ic_selector_close" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/line_top"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:layout_marginTop="@dimen/dimen_15_dp"
|
||||
android:background="@color/color_d8d8d8"
|
||||
app:layout_constraintEnd_toEndOf="@+id/llgroupname"
|
||||
app:layout_constraintStart_toStartOf="@+id/llgroupname"
|
||||
app:layout_constraintTop_toBottomOf="@+id/llgroupname" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvgroup_autojoin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_28_dp"
|
||||
android:text="@string/fun_creategroup_autojoin"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/line_top" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatRadioButton
|
||||
android:id="@+id/rb_selector"
|
||||
style="@style/FunSelectorRadioBtn"
|
||||
android:layout_width="@dimen/dimen_20_dp"
|
||||
android:layout_height="@dimen/dimen_20_dp"
|
||||
android:layout_marginTop="@dimen/dimen_28_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:checked="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/line_top" />
|
||||
|
||||
<View
|
||||
android:id="@+id/rb_clickview"
|
||||
android:layout_width="@dimen/dimen_60_dp"
|
||||
android:layout_height="@dimen/dimen_60_dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/line_top" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvgroup_autojoin_tips"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_10_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_50_dp"
|
||||
android:text="@string/fun_creategroup_autojoin_tips"
|
||||
android:textColor="@color/color_7f7b81"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/tvgroup_autojoin"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvgroup_autojoin" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvgroup_members"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_30_dp"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvgroup_autojoin_tips" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_members"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:paddingHorizontal="@dimen/dimen_15_dp"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvgroup_members" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<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="36dp"
|
||||
android:layout_marginHorizontal="@dimen/dimen_8_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_8_dp"
|
||||
android:background="@drawable/fun_contact_top_search_bg">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivTip"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:src="@drawable/ic_search"
|
||||
android:layout_gravity="center_vertical"
|
||||
app:layout_constraintHorizontal_chainStyle="packed" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_5_dp"
|
||||
android:text="@string/fun_contact_search"
|
||||
android:textColor="@color/color_4d000000"
|
||||
android:textSize="@dimen/dimen_16_dp"
|
||||
app:layout_constraintStart_toEndOf="@id/ivTip"
|
||||
android:layout_gravity="center_vertical"
|
||||
tools:ignore="SpUsage" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/root_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/view_normal_selector"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.RoundFrameLayout
|
||||
android:layout_width="@dimen/dimen_40_dp"
|
||||
android:layout_height="@dimen/dimen_40_dp"
|
||||
android:id="@+id/fl_iv_icon"
|
||||
app:corner_radius="@dimen/dimen_4_dp"
|
||||
android:background="@color/color_white"
|
||||
android:layout_marginTop="@dimen/dimen_12_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_12_dp"
|
||||
android:layout_marginStart="@dimen/dimen_20_dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent">
|
||||
<ImageView
|
||||
android:id="@+id/iv_icon"
|
||||
android:layout_width="@dimen/dimen_40_dp"
|
||||
android:layout_height="@dimen/dimen_40_dp" />
|
||||
</com.netease.yunxin.kit.common.ui.widgets.RoundFrameLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_12_dp"
|
||||
android:textSize="@dimen/text_size_17"
|
||||
android:textColor="@color/color_333333"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="@+id/fl_iv_icon" />
|
||||
|
||||
<TextView android:id="@+id/tv_number"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@+id/iv_arrow"
|
||||
android:background="@drawable/bg_shape_red_dot"
|
||||
android:gravity="center"
|
||||
android:paddingStart="@dimen/dimen_5_dp"
|
||||
android:paddingEnd="@dimen/dimen_5_dp"
|
||||
app:layout_goneMarginRight="@dimen/dimen_20_dp"
|
||||
android:textColor="@color/color_white"
|
||||
android:textSize="@dimen/text_size_12"
|
||||
android:visibility="gone" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_arrow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginRight="@dimen/dimen_20_dp"
|
||||
android:src="@drawable/ic_right_arrow" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:layout_marginStart="@dimen/dimen_20_dp"
|
||||
android:background="@color/color_e5e5e5"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<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:id="@+id/root_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/view_normal_selector">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_selector"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_12_dp"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatRadioButton
|
||||
android:id="@+id/rb_selector"
|
||||
style="@style/FunSelectorRadioBtn"
|
||||
android:layout_width="@dimen/dimen_18_dp"
|
||||
android:layout_height="@dimen/dimen_18_dp"
|
||||
android:clickable="false"
|
||||
android:visibility="visible" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/iv_selector"
|
||||
android:layout_width="@dimen/dimen_18_dp"
|
||||
android:layout_height="@dimen/dimen_18_dp"
|
||||
android:visibility="gone"
|
||||
app:srcCompat="@drawable/fun_ic_notselector_conversation" />
|
||||
</LinearLayout>
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView
|
||||
android:id="@+id/avatar_view"
|
||||
android:layout_width="@dimen/dimen_45_dp"
|
||||
android:layout_height="@dimen/dimen_45_dp"
|
||||
android:layout_marginLeft="@dimen/dimen_12_dp"
|
||||
android:layout_marginTop="@dimen/dimen_10_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_10_dp"
|
||||
app:avatarCorner="@dimen/dimen_45_dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="@+id/layout_selector"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_goneMarginLeft="0dp" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_12_dp"
|
||||
android:layout_marginRight="@dimen/dimen_10_dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintBottom_toTopOf="@+id/messageLayout"
|
||||
app:layout_constraintLeft_toRightOf="@+id/avatar_view"
|
||||
app:layout_constraintRight_toLeftOf="@+id/tv_time"
|
||||
app:layout_constraintTop_toTopOf="@+id/avatar_view" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:textColor="@color/color_7f7b81"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tv_name"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/tv_name" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/messageLayout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/avatar_view"
|
||||
app:layout_constraintLeft_toLeftOf="@+id/tv_name"
|
||||
app:layout_constraintRight_toRightOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/aitTv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dimen_4_dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@string/conversation_ait_tip"
|
||||
android:textColor="@color/color_ff4e54"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_hint"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@string/contact_hint"
|
||||
android:textColor="@color/fun_conversation_item_sub_title_text_color"
|
||||
android:textSize="@dimen/text_size_14" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/unreadTv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="15dp"
|
||||
android:background="@drawable/bg_conversation_red_dot"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
android:paddingStart="@dimen/dimen_5_dp"
|
||||
android:paddingEnd="@dimen/dimen_5_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_15_dp"
|
||||
android:textColor="@color/color_white"
|
||||
android:textSize="@dimen/text_size_12"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:background="@color/color_e5e5e5"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/avatar_view" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/root_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView
|
||||
android:id="@+id/avatar_view"
|
||||
android:layout_width="@dimen/dimen_45_dp"
|
||||
android:layout_height="@dimen/dimen_45_dp"
|
||||
app:avatarCorner="@dimen/dimen_45_dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/ic_clean"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="@+id/avatar_view"
|
||||
app:layout_constraintTop_toTopOf="@+id/avatar_view"
|
||||
app:srcCompat="@drawable/ic_selector_close" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_5_dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_12"
|
||||
app:layout_constraintEnd_toEndOf="@+id/avatar_view"
|
||||
app:layout_constraintStart_toStartOf="@+id/avatar_view"
|
||||
app:layout_constraintTop_toBottomOf="@+id/avatar_view" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<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="match_parent"
|
||||
android:background="@color/color_white">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.BackTitleBar
|
||||
android:id="@+id/fun_title_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/color_fcfcfc"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:titleText="@string/global_search_title"
|
||||
tools:ignore="MissingConstraints" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etSearch"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="@dimen/dimen_16_dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:autofillHints=""
|
||||
android:background="@drawable/bg_search_et"
|
||||
android:drawableStart="@drawable/ic_search"
|
||||
android:drawablePadding="5dp"
|
||||
android:hint="@string/global_search_hint"
|
||||
android:maxLines="1"
|
||||
android:paddingStart="15dp"
|
||||
android:paddingEnd="15dp"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textColorHint="@color/color_666666"
|
||||
android:textSize="14dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/fun_title_bar"
|
||||
tools:ignore="SpUsage" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivClear"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:src="@drawable/ic_clear"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/etSearch"
|
||||
app:layout_constraintEnd_toEndOf="@id/etSearch"
|
||||
app:layout_constraintTop_toTopOf="@id/etSearch" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvSearch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:scrollbars="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/etSearch" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/empty_ll"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_55_dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/etSearch"
|
||||
tools:ignore="MissingConstraints">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivEmpty"
|
||||
android:layout_width="@dimen/dimen_188_dp"
|
||||
android:layout_height="@dimen/dimen_120_dp"
|
||||
android:src="@drawable/fun_ic_contact_empty" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_6_dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/global_search_empty"
|
||||
android:textColor="@color/color_666666"
|
||||
android:textSize="@dimen/text_size_14" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="38dp"
|
||||
android:background="@color/fun_contact_search_item_bg_color">
|
||||
|
||||
<View android:id="@+id/titleDivide"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"
|
||||
tools:ignore="MissingConstraints"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:background="@color/fun_contact_page_bg_color"/>
|
||||
|
||||
<TextView android:id="@+id/tv_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_16_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_20_dp"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:textColor="@color/fun_contact_search_item_title_color"
|
||||
app:layout_constraintTop_toBottomOf="@id/titleDivide"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:gravity="center_vertical"
|
||||
tools:ignore="MissingConstraints" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<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"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="12dp"
|
||||
android:background="@color/fun_contact_search_item_bg_color">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView
|
||||
android:id="@+id/cavUserIcon"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginStart="16dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:avatarCorner="@dimen/dimen_40_dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginStart="68dp"
|
||||
android:layout_marginEnd="15dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:gravity="center_vertical"
|
||||
tools:ignore="MissingConstraints">
|
||||
<TextView
|
||||
android:id="@+id/nickTv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical|start"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/fun_contact_search_item_nick_color"
|
||||
android:textSize="16dp"
|
||||
tools:ignore="SpUsage"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/nameTv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:paddingTop="4dp"
|
||||
android:textColor="@color/fun_contact_search_item_name_color"
|
||||
android:textSize="12dp"
|
||||
tools:ignore="SpUsage"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:visibility="visible"/>
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/root_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/view_normal_selector">
|
||||
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView
|
||||
android:id="@+id/avatar_view"
|
||||
android:layout_width="@dimen/dimen_45_dp"
|
||||
android:layout_height="@dimen/dimen_45_dp"
|
||||
android:layout_marginTop="@dimen/dimen_10_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_10_dp"
|
||||
app:avatarCorner="@dimen/dimen_45_dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_12_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintBottom_toTopOf="@+id/messageLayout"
|
||||
app:layout_constraintLeft_toRightOf="@+id/avatar_view"
|
||||
app:layout_constraintRight_toLeftOf="@+id/tv_time"
|
||||
app:layout_constraintTop_toTopOf="@+id/avatar_view" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:textColor="@color/color_7f7b81"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tv_name"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/tv_name" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/messageLayout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/avatar_view"
|
||||
app:layout_constraintLeft_toLeftOf="@+id/tv_name"
|
||||
app:layout_constraintRight_toRightOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/aitTv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dimen_4_dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@string/conversation_ait_tip"
|
||||
android:textColor="@color/color_ff4e54"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_hint"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/fun_conversation_item_sub_title_text_color"
|
||||
android:textSize="@dimen/text_size_14" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/unreadTv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="15dp"
|
||||
android:background="@drawable/bg_conversation_red_dot"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
android:paddingStart="@dimen/dimen_5_dp"
|
||||
android:paddingEnd="@dimen/dimen_5_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_15_dp"
|
||||
android:textColor="@color/color_white"
|
||||
android:textSize="@dimen/text_size_12"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:layout_marginStart="@dimen/dimen_80_dp"
|
||||
android:background="@color/color_e5e5e5"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/white"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.BackTitleBar
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
|
||||
<com.netease.yunxin.kit.contactkit.ui.view.ContactInfoView
|
||||
android:id="@+id/contact_user"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,125 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<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:id="@+id/root_view"
|
||||
android:background="@android:color/white"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.BackTitleBar
|
||||
android:id="@+id/titleBarView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:titleText="@string/friend_apply" />
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView
|
||||
android:id="@+id/avatar_view"
|
||||
android:layout_width="@dimen/dimen_45_dp"
|
||||
android:layout_height="@dimen/dimen_45_dp"
|
||||
android:layout_marginStart="@dimen/dimen_30_dp"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
app:avatarCorner="@dimen/dimen_45_dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/titleBarView" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/unread_tv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_52_dp"
|
||||
android:layout_marginTop="@dimen/dimen_6_dp"
|
||||
android:background="@drawable/bg_shape_red_dot"
|
||||
android:paddingStart="@dimen/dimen_4_dp"
|
||||
android:paddingEnd="@dimen/dimen_4_dp"
|
||||
android:textColor="@color/color_white"
|
||||
android:textSize="@dimen/text_size_12"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="MissingConstraints" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_15_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_30_dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="start"
|
||||
android:maxWidth="@dimen/verify_name_max_len"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
android:textStyle="bold"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_weight="1"
|
||||
app:layout_constraintStart_toEndOf="@+id/avatar_view"
|
||||
app:layout_constraintTop_toTopOf="@+id/avatar_view" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_action"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dimen_30_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_2_dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="start"
|
||||
android:text="@string/friend_apply"
|
||||
android:maxLines="2"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_weight="1"
|
||||
app:layout_constraintStart_toStartOf="@+id/tv_name"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_name" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_verifytitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:text="@string/fun_verifymsg"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="@+id/avatar_view"
|
||||
app:layout_constraintTop_toBottomOf="@+id/avatar_view" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_verifymsg"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_10_dp"
|
||||
android:background="@drawable/fun_bg_addfriends_verifymsg"
|
||||
android:paddingLeft="@dimen/dimen_10_dp"
|
||||
android:paddingTop="@dimen/dimen_15_dp"
|
||||
android:paddingEnd="@dimen/dimen_10_dp"
|
||||
android:paddingBottom="@dimen/dimen_15_dp"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
app:layout_constraintEnd_toEndOf="@+id/tv_name"
|
||||
app:layout_constraintStart_toStartOf="@+id/avatar_view"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_verifytitle" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_agree"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/dimen_48_dp"
|
||||
android:layout_marginTop="@dimen/dimen_60_dp"
|
||||
android:background="@drawable/fun_positive_btn_bg"
|
||||
android:gravity="center"
|
||||
android:text="@string/contact_verify_agree"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
app:layout_constraintEnd_toEndOf="@+id/tv_name"
|
||||
app:layout_constraintStart_toStartOf="@+id/avatar_view"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_verifymsg" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,160 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<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:id="@+id/root_view"
|
||||
android:background="@android:color/white"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView
|
||||
android:id="@+id/avatar_view"
|
||||
android:layout_width="@dimen/dimen_45_dp"
|
||||
android:layout_height="@dimen/dimen_45_dp"
|
||||
android:layout_marginStart="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_12_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_12_dp"
|
||||
app:avatarCorner="@dimen/dimen_45_dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/unread_tv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_52_dp"
|
||||
android:layout_marginTop="@dimen/dimen_6_dp"
|
||||
android:background="@drawable/bg_shape_red_dot"
|
||||
android:paddingStart="@dimen/dimen_4_dp"
|
||||
android:paddingEnd="@dimen/dimen_4_dp"
|
||||
android:textColor="@color/color_white"
|
||||
android:textSize="@dimen/text_size_12"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="MissingConstraints" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_12_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="start"
|
||||
android:maxWidth="@dimen/verify_name_max_len"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
android:textStyle="bold"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintEnd_toStartOf="@id/lly_operate"
|
||||
app:layout_constraintHorizontal_weight="1"
|
||||
app:layout_constraintStart_toEndOf="@+id/avatar_view"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_action"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_2_dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="start"
|
||||
android:maxLines="1"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
app:layout_constraintEnd_toStartOf="@id/lly_operate"
|
||||
app:layout_constraintHorizontal_weight="1"
|
||||
app:layout_constraintStart_toStartOf="@+id/tv_name"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_name" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/lly_operate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/lly_verify"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_reject"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dimen_10_dp"
|
||||
android:paddingStart="@dimen/dimen_15_dp"
|
||||
android:paddingEnd="@dimen/dimen_15_dp"
|
||||
android:paddingTop="@dimen/dimen_7_dp"
|
||||
android:paddingBottom="@dimen/dimen_7_dp"
|
||||
android:background="@drawable/negative_btn_bg"
|
||||
android:gravity="center"
|
||||
android:text="@string/contact_verify_reject"
|
||||
android:textColor="@color/color_white"
|
||||
android:textSize="@dimen/text_size_14" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_accept"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="@dimen/dimen_15_dp"
|
||||
android:paddingEnd="@dimen/dimen_15_dp"
|
||||
android:paddingTop="@dimen/dimen_7_dp"
|
||||
android:paddingBottom="@dimen/dimen_7_dp"
|
||||
android:background="@drawable/fun_positive_btn_bg"
|
||||
android:gravity="center"
|
||||
android:text="@string/contact_verify_agree"
|
||||
android:textColor="@color/color_white"
|
||||
android:textSize="@dimen/text_size_14" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/lly_verify_result"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/dimen_20_dp"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_verify_result"
|
||||
android:layout_width="@dimen/dimen_16_dp"
|
||||
android:layout_height="@dimen/dimen_16_dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:src="@mipmap/ic_agree_status" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_verify_result"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/dimen_20_dp"
|
||||
android:layout_marginStart="@dimen/dimen_3_dp"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/color_b3b7bc"
|
||||
android:textSize="@dimen/text_size_14" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:background="@color/color_e5e5e5"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/avatar_view" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
12
contactkit-ui/src/main/res-fun/values/colors.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="fun_contact_page_bg_color">#ededed</color>
|
||||
<!-- search page-->
|
||||
<color name="fun_contact_search_hit_text_color">#58BE6B</color>
|
||||
<color name="fun_contact_search_edit_bg_color">#FFFFFF</color>
|
||||
<color name="fun_contact_search_item_bg_color">#FFFFFF</color>
|
||||
<color name="fun_contact_search_item_title_color">#737373</color>
|
||||
<color name="fun_contact_search_item_nick_color">#333333</color>
|
||||
<color name="fun_contact_search_item_name_color">#666666</color>
|
||||
<color name="fun_contact_list_item_hint_color">#7F7B81</color>
|
||||
</resources>
|
||||
33
contactkit-ui/src/main/res-fun/values/styles.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<style name="FunSelectorRadioBtn" parent="Widget.AppCompat.CompoundButton.RadioButton">
|
||||
<item name="android:button">@null</item>
|
||||
<item name="android:background">@drawable/fun_radio_button_selector</item>
|
||||
</style>
|
||||
|
||||
<style name="SelectorFriendsBottomDialogTheme" parent="ThemeOverlay.AppCompat.Dialog">
|
||||
<!-- 背景透明 -->
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
<item name="android:colorBackgroundCacheHint">@null</item>
|
||||
<!-- Dialog以外的区域模糊效果 -->
|
||||
<item name="android:backgroundDimEnabled">true</item>
|
||||
<!-- 半透明 -->
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
<item name="android:windowAnimationStyle">@style/BottomDialogAnimation</item>
|
||||
<!-- 浮于Activity之上 -->
|
||||
<item name="android:windowIsFloating">false</item>
|
||||
<item name="android:windowFullscreen">false</item>
|
||||
<!-- 无标题 -->
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<!-- 边框 -->
|
||||
<item name="android:windowFrame">@null</item>
|
||||
<item name="android:windowCloseOnTouchOutside">false</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
After Width: | Height: | Size: 9.9 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
116
contactkit-ui/src/main/res-normal/layout/add_friend_activity.xml
Normal file
@@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<LinearLayout android:id="@+id/layout_add_friend_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/page_title_bar_height"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="MissingConstraints">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_add_friend_back"
|
||||
android:layout_width="@dimen/image_operate_width_height"
|
||||
android:layout_height="@dimen/image_operate_width_height"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginLeft="@dimen/page_margin_left_right"
|
||||
android:src="@mipmap/ic_back" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_add_friend_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/add_friend_title"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:textColor="@color/title_color"
|
||||
android:textStyle="bold"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_marginLeft="@dimen/page_margin_left_right"
|
||||
android:layout_marginRight="@dimen/page_margin_left_right" />
|
||||
|
||||
<TextView android:id="@+id/tv_add_friend_more"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="@dimen/image_operate_width_height"
|
||||
android:layout_height="@dimen/image_operate_width_height"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout android:id="@+id/layout_add_friend_input"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_32_dp"
|
||||
android:background="@color/color_f2f4f5"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginLeft="@dimen/page_margin_left_right"
|
||||
android:layout_marginRight="@dimen/page_margin_left_right"
|
||||
android:layout_marginTop="@dimen/dimen_12_dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/layout_add_friend_title"
|
||||
tools:ignore="MissingConstraints" >
|
||||
|
||||
<ImageView
|
||||
android:src="@mipmap/ic_search"
|
||||
android:layout_marginLeft="@dimen/dimen_12_dp"
|
||||
android:layout_marginRight="@dimen/dimen_12_dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="@dimen/dimen_12_dp"
|
||||
android:layout_height="@dimen/dimen_12_dp"/>
|
||||
|
||||
<EditText android:id="@+id/et_add_friend_account"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="@null"
|
||||
android:textCursorDrawable="@null"
|
||||
android:imeOptions="actionSearch"
|
||||
android:singleLine="true"
|
||||
android:layout_marginRight="@dimen/dimen_12_dp"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:hint="@string/add_friend_search_hint"/>
|
||||
|
||||
<ImageView android:id="@+id/iv_friend_clear"
|
||||
android:src="@drawable/ic_clear"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="@dimen/dimen_12_dp"
|
||||
android:layout_marginRight="@dimen/dimen_12_dp"
|
||||
android:layout_width="@dimen/dimen_12_dp"
|
||||
android:layout_height="@dimen/dimen_12_dp"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout android:id="@+id/add_friend_empty_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/layout_add_friend_input"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintVertical_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
tools:ignore="MissingConstraints" >
|
||||
<ImageView
|
||||
android:id="@+id/empty_state_iv"
|
||||
android:layout_width="@dimen/dimen_188_dp"
|
||||
android:layout_height="@dimen/verify_name_max_len"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="@dimen/dimen_70_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_16_dp"
|
||||
android:src="@drawable/ic_contact_empty"/>
|
||||
|
||||
<TextView android:id="@+id/add_friend_empty_tv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/add_friend_search_empty_tips"
|
||||
android:textColor="@color/color_b3b7bc"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/root_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView
|
||||
android:id="@+id/avatar_view"
|
||||
android:layout_width="@dimen/image_contact_width_height"
|
||||
android:layout_height="@dimen/image_contact_width_height"
|
||||
android:layout_marginTop="@dimen/dimen_12_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_12_dp"
|
||||
android:layout_marginStart="@dimen/dimen_20_dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_12_dp"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:textColor="@color/color_14131b"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
app:layout_constrainedWidth="true"
|
||||
android:layout_marginEnd="@dimen/dimen_100_dp"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="@+id/avatar_view" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_relieve"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/color_337eff"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:paddingHorizontal="@dimen/dimen_16_dp"
|
||||
android:paddingVertical="@dimen/dimen_8_dp"
|
||||
android:background="@drawable/positive_btn_bg"
|
||||
android:layout_marginEnd="@dimen/dimen_20_dp"
|
||||
android:text="@string/contact_black_list_relieve"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/color_eff1f4"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.BackTitleBar
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.CleanableEditText
|
||||
android:id="@+id/edt_comment"
|
||||
android:layout_width="match_parent"
|
||||
android:maxLength="15"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/dimen_20_dp" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="MissingDefaultResource">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/contact_fragment_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<com.netease.yunxin.kit.contactkit.ui.view.ContactLayout
|
||||
android:id="@+id/contact_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"/>
|
||||
|
||||
<LinearLayout android:id="@+id/empty_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_188_dp"
|
||||
android:layout_marginTop="400dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:visibility="gone"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/dimen_118_dp"
|
||||
android:layout_height="@dimen/dimen_96_dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:src="@drawable/ic_contact_empty"/>
|
||||
|
||||
<TextView android:id="@+id/empty_tv"
|
||||
android:layout_width="@dimen/dimen_118_dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center"
|
||||
android:text="@string/selector_friend_empty"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/white"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.BackTitleBar
|
||||
android:id="@+id/title"
|
||||
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_selected"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/color_f2f4f5"
|
||||
android:paddingHorizontal="@dimen/dimen_20_dp" />
|
||||
|
||||
|
||||
<com.netease.yunxin.kit.contactkit.ui.view.ContactListView
|
||||
android:id="@+id/contact_listView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:showSelector="true" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/empty_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_188_dp"
|
||||
android:layout_marginTop="@dimen/dimen_150_dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/dimen_118_dp"
|
||||
android:layout_height="@dimen/dimen_96_dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:src="@drawable/ic_contact_empty" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty_tv"
|
||||
android:layout_width="@dimen/dimen_118_dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center"
|
||||
android:text="@string/selector_friend_empty" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/root_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/view_normal_selector"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.RoundFrameLayout
|
||||
android:layout_width="@dimen/image_contact_width_height"
|
||||
android:layout_height="@dimen/image_contact_width_height"
|
||||
android:id="@+id/fl_iv_icon"
|
||||
app:corner_radius="@dimen/dimen_30_dp"
|
||||
android:background="@color/color_white"
|
||||
android:layout_marginTop="@dimen/dimen_12_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_12_dp"
|
||||
android:layout_marginStart="@dimen/dimen_20_dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent">
|
||||
<ImageView
|
||||
android:id="@+id/iv_icon"
|
||||
android:layout_width="@dimen/image_contact_width_height"
|
||||
android:layout_height="@dimen/image_contact_width_height" />
|
||||
</com.netease.yunxin.kit.common.ui.widgets.RoundFrameLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_12_dp"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:textColor="@color/color_14131b"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="@+id/fl_iv_icon" />
|
||||
|
||||
<TextView android:id="@+id/tv_number"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@+id/iv_arrow"
|
||||
android:background="@drawable/bg_shape_red_dot"
|
||||
android:gravity="center"
|
||||
android:paddingStart="@dimen/dimen_5_dp"
|
||||
android:paddingEnd="@dimen/dimen_5_dp"
|
||||
android:textColor="@color/color_white"
|
||||
android:textSize="@dimen/text_size_12"
|
||||
android:visibility="gone" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_arrow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginRight="@dimen/dimen_20_dp"
|
||||
android:src="@drawable/ic_right_arrow" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:layout_marginStart="@dimen/dimen_20_dp"
|
||||
android:background="@color/color_f5f8fc"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/root_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="@dimen/dimen_8_dp"
|
||||
android:paddingEnd="@dimen/dimen_20_dp"
|
||||
android:background="@drawable/view_normal_selector"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatRadioButton
|
||||
android:id="@+id/rb_selector"
|
||||
android:layout_width="@dimen/dimen_18_dp"
|
||||
android:layout_height="@dimen/dimen_18_dp"
|
||||
android:layout_marginStart="@dimen/dimen_12_dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
style="@style/SelectorRadioBtn"
|
||||
android:clickable="false"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView
|
||||
android:id="@+id/avatar_view"
|
||||
android:layout_width="@dimen/image_contact_width_height"
|
||||
android:layout_height="@dimen/image_contact_width_height"
|
||||
android:layout_marginTop="@dimen/dimen_12_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_12_dp"
|
||||
android:layout_marginStart="@dimen/dimen_12_dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="@+id/rb_selector" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_12_dp"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:textColor="@color/color_14131b"
|
||||
android:maxLines="1"
|
||||
app:layout_constrainedWidth="true"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="@+id/avatar_view"
|
||||
tools:text="@string/comment_name" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/root_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/dimen_7_dp"
|
||||
android:paddingBottom="@dimen/dimen_9_dp"
|
||||
android:paddingEnd="@dimen/dimen_10_dp"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView
|
||||
android:id="@+id/avatar_view"
|
||||
android:layout_width="@dimen/image_contact_width_height"
|
||||
android:layout_height="@dimen/image_contact_width_height"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<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="match_parent">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.BackTitleBar
|
||||
android:id="@+id/global_title_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_46_dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:titleText="@string/global_search_title"
|
||||
tools:ignore="MissingConstraints" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etSearch"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="@dimen/dimen_16_dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:autofillHints=""
|
||||
android:background="@drawable/bg_search_et"
|
||||
android:drawableStart="@drawable/ic_search"
|
||||
android:drawablePadding="5dp"
|
||||
android:hint="@string/global_search_hint"
|
||||
android:maxLines="1"
|
||||
android:paddingStart="15dp"
|
||||
android:paddingEnd="15dp"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textColorHint="@color/color_666666"
|
||||
android:textSize="14dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/global_title_bar"
|
||||
tools:ignore="SpUsage" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivClear"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:src="@drawable/ic_clear"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/etSearch"
|
||||
app:layout_constraintEnd_toEndOf="@id/etSearch"
|
||||
app:layout_constraintTop_toTopOf="@id/etSearch" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvSearch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:scrollbars="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/etSearch" />
|
||||
|
||||
<LinearLayout android:id="@+id/empty_ll"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_55_dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/etSearch"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="MissingConstraints"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivEmpty"
|
||||
android:layout_width="@dimen/dimen_188_dp"
|
||||
android:layout_height="@dimen/dimen_120_dp"
|
||||
android:src="@drawable/ic_contact_empty"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/global_search_empty"
|
||||
android:textColor="@color/color_666666"
|
||||
android:layout_marginTop="@dimen/dimen_6_dp"
|
||||
android:gravity="center"
|
||||
android:textSize="@dimen/text_size_14"/>
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_36_dp"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<TextView android:id="@+id/tv_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_20_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_20_dp"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:textColor="@color/color_b3b7bc"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:gravity="center_vertical"
|
||||
tools:ignore="MissingConstraints" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:background="@color/color_d9d9d9"
|
||||
android:layout_marginStart="@dimen/dimen_20_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_20_dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<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"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="10dp">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView
|
||||
android:id="@+id/cavUserIcon"
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="42dp"
|
||||
android:layout_marginStart="20dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginStart="77dp"
|
||||
android:layout_marginEnd="15dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:gravity="center_vertical"
|
||||
tools:ignore="MissingConstraints">
|
||||
<TextView
|
||||
android:id="@+id/tvNickName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:gravity="center_vertical|start"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="16dp"
|
||||
android:ellipsize="end"
|
||||
tools:ignore="SpUsage" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:paddingTop="4dp"
|
||||
android:textColor="@color/color_666666"
|
||||
android:textSize="12dp"
|
||||
tools:ignore="SpUsage"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:visibility="visible"/>
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/root_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:background="@drawable/view_normal_selector"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView
|
||||
android:id="@+id/avatar_view"
|
||||
android:layout_width="@dimen/dimen_42_dp"
|
||||
android:layout_height="@dimen/dimen_42_dp"
|
||||
android:layout_marginVertical="@dimen/dimen_12_dp"
|
||||
android:layout_marginStart="@dimen/dimen_20_dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_14_dp"
|
||||
android:textColor="@color/color_14131b"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="@dimen/dimen_20_dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.BackTitleBar
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
|
||||
<com.netease.yunxin.kit.contactkit.ui.view.ContactInfoView
|
||||
android:id="@+id/contact_user"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,139 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/root_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView
|
||||
android:id="@+id/avatar_view"
|
||||
android:layout_width="@dimen/image_contact_width_height"
|
||||
android:layout_height="@dimen/image_contact_width_height"
|
||||
android:layout_marginTop="@dimen/dimen_12_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_12_dp"
|
||||
android:layout_marginStart="@dimen/dimen_20_dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent" />
|
||||
|
||||
<TextView android:id="@+id/unread_tv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_shape_red_dot"
|
||||
android:paddingStart="@dimen/dimen_4_dp"
|
||||
android:paddingEnd="@dimen/dimen_4_dp"
|
||||
android:textColor="@color/color_white"
|
||||
android:textSize="@dimen/text_size_12"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginTop="@dimen/dimen_12_dp"
|
||||
android:layout_marginStart="@dimen/dimen_42_dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
tools:ignore="MissingConstraints" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintHorizontal_weight="1"
|
||||
android:layout_marginStart="@dimen/dimen_16_dp"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:textColor="@color/color_14131b"
|
||||
android:maxLines="1"
|
||||
android:layout_marginTop="@dimen/dimen_15_dp"
|
||||
android:maxWidth="@dimen/verify_name_max_len"
|
||||
app:layout_constrainedWidth="true"
|
||||
android:ellipsize="end"
|
||||
android:gravity="start"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/lly_operate"
|
||||
app:layout_constraintStart_toEndOf="@+id/avatar_view"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_action"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintHorizontal_weight="1"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/tv_name"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_name"
|
||||
app:layout_constraintEnd_toStartOf="@id/lly_operate"
|
||||
android:gravity="start"
|
||||
android:layout_marginBottom="@dimen/dimen_3_dp"/>
|
||||
|
||||
<LinearLayout android:id="@+id/lly_operate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dimen_20_dp"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/lly_verify"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_reject"
|
||||
android:layout_width="@dimen/dimen_60_dp"
|
||||
android:layout_height="@dimen/dimen_32_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_8_dp"
|
||||
android:background="@drawable/negative_btn_bg"
|
||||
android:gravity="center"
|
||||
android:text="@string/contact_verify_reject"
|
||||
android:textColor="@color/title_color"
|
||||
android:textSize="@dimen/text_size_14" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_accept"
|
||||
android:layout_width="@dimen/dimen_60_dp"
|
||||
android:layout_height="@dimen/dimen_32_dp"
|
||||
android:background="@drawable/positive_btn_bg"
|
||||
android:text="@string/contact_verify_agree"
|
||||
android:textColor="@color/color_337eff"
|
||||
android:gravity="center"
|
||||
android:textSize="@dimen/text_size_14" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/lly_verify_result"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/dimen_20_dp"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_verify_result"
|
||||
android:layout_width="@dimen/dimen_16_dp"
|
||||
android:layout_height="@dimen/dimen_16_dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:src="@mipmap/ic_agree_status" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_verify_result"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/dimen_20_dp"
|
||||
android:layout_marginStart="@dimen/dimen_3_dp"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/color_b3b7bc"
|
||||
android:textSize="@dimen/text_size_14" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
13
contactkit-ui/src/main/res-normal/values/styles.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<style name="SelectorRadioBtn" parent="Widget.AppCompat.CompoundButton.RadioButton">
|
||||
<item name="android:button">@drawable/radio_button_selector</item>
|
||||
</style>
|
||||
</resources>
|
||||
14
contactkit-ui/src/main/res/drawable/bg_search_et.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="4dp" />
|
||||
<solid android:color="@color/color_f2f4f5"/>
|
||||
|
||||
</shape>
|
||||
9
contactkit-ui/src/main/res/drawable/bg_shape_red_dot.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Copyright (c) 2022 NetEase, Inc. All rights reserved. -->
|
||||
<!-- Use of this source code is governed by a MIT license that can be -->
|
||||
<!-- found in the LICENSE file. -->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="9dp" />
|
||||
<solid android:color="@color/color_f24957" />
|
||||
</shape>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<corners android:radius="@dimen/dimen_20_dp" />
|
||||
|
||||
<solid android:color="@color/color_6d94ff"/>
|
||||
</shape>
|
||||
18
contactkit-ui/src/main/res/drawable/ic_back.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="26dp"
|
||||
android:height="26dp"
|
||||
android:viewportWidth="26"
|
||||
android:viewportHeight="26">
|
||||
<path
|
||||
android:pathData="M0,0h26v26h-26z"
|
||||
android:fillColor="#00000000" />
|
||||
<path
|
||||
android:pathData="M17.7071,5.7071C18.0976,5.3166 18.0976,4.6834 17.7071,4.2929C17.3166,3.9024 16.6834,3.9024 16.2929,4.2929L17.7071,5.7071ZM9,13L8.2929,12.2929C7.9024,12.6834 7.9024,13.3166 8.2929,13.7071L9,13ZM15.7929,21.2071C16.1834,21.5976 16.8166,21.5976 17.2071,21.2071C17.5976,20.8166 17.5976,20.1834 17.2071,19.7929L15.7929,21.2071ZM16.2929,4.2929L8.2929,12.2929L9.7071,13.7071L17.7071,5.7071L16.2929,4.2929ZM8.2929,13.7071L15.7929,21.2071L17.2071,19.7929L9.7071,12.2929L8.2929,13.7071Z"
|
||||
android:fillColor="#333333" />
|
||||
</vector>
|
||||
15
contactkit-ui/src/main/res/drawable/ic_clear.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="16dp"
|
||||
android:height="16dp"
|
||||
android:viewportWidth="16"
|
||||
android:viewportHeight="16">
|
||||
<path
|
||||
android:pathData="M8,0C3.5891,0 0,3.5884 0,8C0,12.4116 3.5884,16 8,16C12.4109,16 16,12.4116 16,8C16,3.5884 12.4116,0 8,0ZM11.2633,10.464C11.3191,10.5165 11.3638,10.5796 11.3948,10.6497C11.4257,10.7198 11.4423,10.7954 11.4434,10.872C11.4446,10.9486 11.4303,11.0246 11.4015,11.0956C11.3727,11.1666 11.3299,11.2311 11.2757,11.2852C11.2215,11.3393 11.1569,11.382 11.0859,11.4107C11.0149,11.4393 10.9388,11.4535 10.8622,11.4522C10.7856,11.4509 10.71,11.4342 10.64,11.4031C10.57,11.372 10.5069,11.3272 10.4545,11.2713L7.9971,8.8058L5.5316,11.2451C5.4792,11.3017 5.4158,11.347 5.3453,11.3785C5.2748,11.4099 5.1987,11.4267 5.1216,11.428C5.0444,11.4292 4.9678,11.4148 4.8964,11.3856C4.825,11.3564 4.7602,11.3131 4.7059,11.2582C4.6517,11.2033 4.6091,11.1381 4.5808,11.0663C4.5525,10.9945 4.5389,10.9177 4.5411,10.8406C4.5432,10.7635 4.5609,10.6876 4.5932,10.6175C4.6254,10.5474 4.6715,10.4845 4.7287,10.4327L7.1905,7.9971L4.7375,5.536C4.6835,5.4831 4.6405,5.42 4.6111,5.3503C4.5816,5.2807 4.5663,5.2059 4.566,5.1302C4.5657,5.0546 4.5803,4.9797 4.6092,4.9098C4.638,4.8399 4.6804,4.7764 4.734,4.723C4.7875,4.6697 4.8511,4.6274 4.9211,4.5988C4.991,4.5701 5.066,4.5556 5.1416,4.5562C5.2172,4.5567 5.292,4.5722 5.3615,4.6018C5.4311,4.6315 5.4941,4.6746 5.5469,4.7287L8.0036,7.1934L10.4691,4.7542C10.5224,4.7015 10.5856,4.6598 10.6551,4.6315C10.7245,4.6032 10.7989,4.5888 10.8739,4.5893C10.9489,4.5897 11.0231,4.6049 11.0922,4.634C11.1613,4.6631 11.224,4.7056 11.2767,4.7589C11.3294,4.8123 11.3711,4.8755 11.3994,4.9449C11.4277,5.0144 11.4421,5.0887 11.4416,5.1637C11.4412,5.2387 11.426,5.3129 11.3969,5.382C11.3678,5.4511 11.3253,5.5138 11.272,5.5665L8.8095,8.0029L11.2633,10.464Z"
|
||||
android:fillColor="#B3B7BC" />
|
||||
</vector>
|
||||
16
contactkit-ui/src/main/res/drawable/ic_right_arrow.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="16dp"
|
||||
android:height="16dp"
|
||||
android:viewportWidth="16"
|
||||
android:viewportHeight="16">
|
||||
|
||||
<path
|
||||
android:pathData="M5.1032,3.5123C4.8629,3.272 4.8629,2.8823 5.1032,2.642C5.3435,2.4017 5.7332,2.4017 5.9735,2.642L5.1032,3.5123ZM10.4614,8.0002L10.8966,7.5651C11.1369,7.8054 11.1369,8.1951 10.8966,8.4354L10.4614,8.0002ZM6.2812,13.0508C6.0409,13.2911 5.6512,13.2911 5.4109,13.0508C5.1706,12.8104 5.1706,12.4208 5.4109,12.1805L6.2812,13.0508ZM5.9735,2.642L10.8966,7.5651L10.0263,8.4354L5.1032,3.5123L5.9735,2.642ZM10.8966,8.4354L6.2812,13.0508L5.4109,12.1805L10.0263,7.5651L10.8966,8.4354Z"
|
||||
android:fillColor="#999999" />
|
||||
</vector>
|
||||
15
contactkit-ui/src/main/res/drawable/ic_search.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="16dp"
|
||||
android:height="16dp"
|
||||
android:viewportWidth="16"
|
||||
android:viewportHeight="16">
|
||||
<path
|
||||
android:pathData="M6.9706,2.7743C9.12,2.7777 10.9176,4.4086 11.1293,6.5476C11.3413,8.6866 9.8984,10.6385 7.7916,11.0634C5.6845,11.4884 3.598,10.2484 2.9643,8.1945C2.3305,6.1405 3.3552,3.9405 5.3352,3.1042C5.8526,2.8853 6.4088,2.7731 6.9706,2.7743ZM6.9706,1.8046C4.1144,1.8046 1.7988,4.1201 1.7988,6.9763C1.7988,9.8324 4.1144,12.148 6.9706,12.148C9.8267,12.148 12.1423,9.8324 12.1423,6.9763C12.1423,4.1201 9.8267,1.8046 6.9706,1.8046ZM13.7099,14.2005C13.6462,14.2007 13.5831,14.1881 13.5243,14.1637C13.4654,14.1393 13.412,14.1035 13.3671,14.0583L10.9105,11.6017C10.7269,11.4114 10.7295,11.109 10.9164,10.9219C11.1035,10.7349 11.4059,10.7322 11.596,10.9161L14.0526,13.3726C14.1203,13.4405 14.1665,13.5268 14.1852,13.6209C14.2039,13.7149 14.1943,13.8123 14.1576,13.9009C14.121,13.9896 14.059,14.0654 13.9793,14.1187C13.8996,14.172 13.8058,14.2005 13.7099,14.2005Z"
|
||||
android:fillColor="#A6ADB6"/>
|
||||
</vector>
|
||||
16
contactkit-ui/src/main/res/drawable/negative_btn_bg.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="@dimen/dimen_20_dp" />
|
||||
|
||||
<solid
|
||||
android:width="@dimen/dimen_1_dp"
|
||||
android:color="@color/color_fe6881" />
|
||||
|
||||
</shape>
|
||||
16
contactkit-ui/src/main/res/drawable/positive_btn_bg.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="4dp" />
|
||||
|
||||
<stroke
|
||||
android:width="@dimen/dimen_1_dp"
|
||||
android:color="@color/color_337eff" />
|
||||
|
||||
</shape>
|
||||
@@ -0,0 +1,15 @@
|
||||
<!-- Copyright (c) 2022 NetEase, Inc. All rights reserved. -->
|
||||
<!-- Use of this source code is governed by a MIT license that can be -->
|
||||
<!-- found in the LICENSE file. -->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="18dp"
|
||||
android:height="18dp"
|
||||
android:viewportWidth="18"
|
||||
android:viewportHeight="18">
|
||||
<path
|
||||
android:strokeWidth="1"
|
||||
android:pathData="M9,9m-8.5,0a8.5,8.5 0,1 1,17 0a8.5,8.5 0,1 1,-17 0"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#969AA0" />
|
||||
</vector>
|
||||
@@ -0,0 +1,16 @@
|
||||
<!-- Copyright (c) 2022 NetEase, Inc. All rights reserved. -->
|
||||
<!-- Use of this source code is governed by a MIT license that can be -->
|
||||
<!-- found in the LICENSE file. -->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="18dp"
|
||||
android:height="18dp"
|
||||
android:viewportWidth="18"
|
||||
android:viewportHeight="18">
|
||||
<path
|
||||
android:pathData="M9,9m-9,0a9,9 0,1 1,18 0a9,9 0,1 1,-18 0"
|
||||
android:fillColor="#337EFF" />
|
||||
<path
|
||||
android:pathData="M5.1508,8.7407C4.7315,8.3813 4.1002,8.4299 3.7407,8.8492C3.3813,9.2685 3.4299,9.8998 3.8492,10.2593L5.1508,8.7407ZM8,12.5L7.3492,13.2593C7.7587,13.6102 8.3727,13.5733 8.7372,13.1757L8,12.5ZM14.2372,7.1757C14.6103,6.7686 14.5828,6.136 14.1757,5.7628C13.7686,5.3896 13.136,5.4172 12.7628,5.8243L14.2372,7.1757ZM3.8492,10.2593L7.3492,13.2593L8.6508,11.7407L5.1508,8.7407L3.8492,10.2593ZM8.7372,13.1757L14.2372,7.1757L12.7628,5.8243L7.2628,11.8243L8.7372,13.1757Z"
|
||||
android:fillColor="#ffffff" />
|
||||
</vector>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Copyright (c) 2022 NetEase, Inc. All rights reserved. -->
|
||||
<!-- Use of this source code is governed by a MIT license that can be -->
|
||||
<!-- found in the LICENSE file. -->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@drawable/radio_button_selected" android:state_checked="true" />
|
||||
|
||||
<item android:drawable="@drawable/radio_button_not_selected" android:state_checked="false" />
|
||||
|
||||
</selector>
|
||||
17
contactkit-ui/src/main/res/drawable/switch_thumb_off.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<size
|
||||
android:width="@dimen/dimen_20_dp"
|
||||
android:height="@dimen/dimen_20_dp" />
|
||||
|
||||
<solid android:color="@color/color_white" />
|
||||
<stroke android:width="1dp" android:color="@color/color_dbdde4"/>
|
||||
|
||||
</shape>
|
||||
17
contactkit-ui/src/main/res/drawable/switch_thumb_on.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<size
|
||||
android:width="@dimen/dimen_20_dp"
|
||||
android:height="@dimen/dimen_20_dp" />
|
||||
|
||||
<solid android:color="@color/color_white" />
|
||||
<stroke android:width="1dp" android:color="@color/color_337eff"/>
|
||||
|
||||
</shape>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@drawable/switch_thumb_on" android:state_checked="true" />
|
||||
|
||||
<item android:drawable="@drawable/switch_thumb_off" android:state_checked="false" />
|
||||
|
||||
</selector>
|
||||
19
contactkit-ui/src/main/res/drawable/switch_track_off.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="@dimen/dimen_12_dp"/>
|
||||
|
||||
<size
|
||||
android:width="@dimen/dimen_44_dp"
|
||||
android:height="@dimen/dimen_24_dp" />
|
||||
|
||||
<solid android:color="@color/color_eeeeee" />
|
||||
|
||||
</shape>
|
||||
19
contactkit-ui/src/main/res/drawable/switch_track_on.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="@dimen/dimen_12_dp" />
|
||||
|
||||
<size
|
||||
android:width="@dimen/dimen_44_dp"
|
||||
android:height="@dimen/dimen_24_dp" />
|
||||
|
||||
<solid android:color="@color/color_09bb07" />
|
||||
|
||||
</shape>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@drawable/switch_track_on" android:state_checked="true" />
|
||||
|
||||
<item android:drawable="@drawable/switch_track_off" android:state_checked="false" />
|
||||
|
||||
</selector>
|
||||
12
contactkit-ui/src/main/res/drawable/view_normal_selector.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<selector xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" tools:ignore="MissingDefaultResource">
|
||||
|
||||
<item android:drawable="@color/color_white" android:state_pressed="false" />
|
||||
<item android:drawable="@color/color_ededef" android:state_pressed="true" />
|
||||
</selector>
|
||||
@@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/color_white"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.BackTitleBar
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_Tips"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/dimen_15_dp"
|
||||
android:layout_marginVertical="@dimen/dimen_4_dp"
|
||||
android:lineSpacingExtra="@dimen/dimen_5_dp"
|
||||
android:textColor="@color/color_999999"
|
||||
android:textSize="@dimen/text_size_14"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/heimindan_tv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_40_dp"
|
||||
android:text="@string/black_list"
|
||||
android:textColor="#ff333333"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.netease.yunxin.kit.contactkit.ui.view.ContactListView
|
||||
android:id="@+id/contact_listView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="@dimen/dimen_15_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:layout_weight="0.9"
|
||||
android:background="@android:color/white"
|
||||
app:showIndexBar="false" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layoutEmpty"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="0.9"
|
||||
android:background="@android:color/white"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/dimen_100_dp"
|
||||
android:layout_height="@dimen/dimen_100_dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:src="@mipmap/ic_nodate" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty_tv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/nodate_txt" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_blackremove"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_40_dp"
|
||||
android:layout_marginStart="@dimen/dimen_15_dp"
|
||||
android:layout_marginTop="@dimen/dimen_20_dp"
|
||||
android:layout_marginEnd="@dimen/dimen_15_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_20_dp"
|
||||
android:background="@drawable/fun_themeblue_btn_bg"
|
||||
android:gravity="center"
|
||||
android:text="@string/removeblack_txt"
|
||||
android:textColor="@android:color/white"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
</FrameLayout>
|
||||
55
contactkit-ui/src/main/res/layout/contact_list_view.xml
Normal file
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/contactList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent" />
|
||||
|
||||
<com.netease.yunxin.kit.contactkit.ui.indexbar.IndexBar
|
||||
android:id="@+id/index_bar"
|
||||
android:layout_width="@dimen/dimen_13_dp"
|
||||
android:visibility="gone"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/dimen_115_dp"
|
||||
android:layout_marginBottom="@dimen/dimen_118_dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:indexBarTextSize="@dimen/text_size_8" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/contact_empty_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/color_white"
|
||||
android:visibility="gone" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/emptyStateIv"
|
||||
android:layout_width="@dimen/dimen_120_dp"
|
||||
android:layout_height="@dimen/dimen_92_dp"
|
||||
android:src="@drawable/ic_contact_empty"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="@dimen/dimen_150_dp"/>
|
||||
|
||||
<TextView android:id="@+id/contact_empty_tv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="250dp"
|
||||
android:layout_gravity="center_horizontal"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
61
contactkit-ui/src/main/res/layout/contact_view_layout.xml
Normal file
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<LinearLayout android:id="@+id/contact_header_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.TitleBarView
|
||||
android:id="@+id/contact_title_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_52_dp"
|
||||
app:head_title="@string/contact_title"
|
||||
app:head_title_color="@color/title_color"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/divide_line_top_for_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:background="@color/color_e9eff5"
|
||||
android:alpha="0.6"
|
||||
tools:ignore="MissingConstraints" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout android:id="@+id/contact_body_top_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
</FrameLayout>
|
||||
<FrameLayout android:id="@+id/contact_body_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
<com.netease.yunxin.kit.contactkit.ui.view.ContactListView
|
||||
android:id="@+id/contact_listview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:head_img_visible="gone"
|
||||
app:head_title="@string/contact_title"
|
||||
app:head_title_color="@color/title_color"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout android:id="@+id/contact_bottom_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</merge>
|
||||
312
contactkit-ui/src/main/res/layout/user_info_layout.xml
Normal file
@@ -0,0 +1,312 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
<FrameLayout 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="match_parent"
|
||||
android:background="@color/color_white">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/color_white"
|
||||
android:orientation="vertical">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/dimen_20_dp"
|
||||
android:layout_marginVertical="@dimen/dimen_15_dp">
|
||||
|
||||
<com.netease.yunxin.kit.common.ui.widgets.ContactAvatarView
|
||||
android:id="@+id/avatar_view"
|
||||
android:layout_width="@dimen/dimen_60_dp"
|
||||
android:layout_height="@dimen/dimen_60_dp"
|
||||
app:avatarTextSize="@dimen/text_size_22"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dimen_20_dp"
|
||||
android:textColor="@color/title_color"
|
||||
android:textSize="@dimen/text_size_22"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/avatar_view" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_account"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/dimen_12_dp"
|
||||
android:textColor="@color/color_666666"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:layout_marginStart="@dimen/dimen_20_dp"
|
||||
android:layout_marginTop="@dimen/dimen_4_dp"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_name"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/avatar_view"
|
||||
tools:ignore="SpUsage" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_comment_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/dimen_12_dp"
|
||||
android:textColor="@color/color_666666"
|
||||
android:layout_marginStart="@dimen/dimen_20_dp"
|
||||
android:visibility="gone"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_account"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/avatar_view"
|
||||
tools:ignore="SpUsage" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:layout_marginStart="@dimen/dimen_20_dp"
|
||||
android:background="@color/color_f5f8fc" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rly_comment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_46_dp"
|
||||
android:paddingHorizontal="@dimen/dimen_20_dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_comment"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="@string/comment_name"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
android:textColor="@color/title_color" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/ic_right_arrow" />
|
||||
</RelativeLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/divide_line1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_6_dp"
|
||||
android:background="@color/color_eff1f4" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/lly_friend"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_46_dp"
|
||||
android:paddingHorizontal="@dimen/dimen_20_dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="@string/birthday"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
android:textColor="@color/title_color" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_birthday"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:textSize="@dimen/text_size_12"
|
||||
android:textColor="@color/color_a6adb6" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:background="@color/color_f5f8fc" />
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_46_dp"
|
||||
android:paddingHorizontal="@dimen/dimen_20_dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="@string/phone"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
android:textColor="@color/title_color" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_phone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:textSize="@dimen/text_size_12"
|
||||
android:textColor="@color/color_a6adb6" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:background="@color/color_f5f8fc" />
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_46_dp"
|
||||
android:paddingHorizontal="@dimen/dimen_20_dp">
|
||||
|
||||
<TextView android:id="@+id/tv_email_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/email"
|
||||
android:layout_centerVertical="true"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
android:textColor="@color/title_color" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_email"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:textSize="@dimen/text_size_12"
|
||||
android:layout_marginStart="@dimen/dimen_45_dp"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:textColor="@color/color_a6adb6" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:background="@color/color_f5f8fc" />
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_46_dp"
|
||||
android:paddingHorizontal="@dimen/dimen_20_dp">
|
||||
|
||||
<TextView android:id="@+id/tv_signature_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/personal_signature"
|
||||
android:layout_centerVertical="true"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
android:textColor="@color/title_color" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_signature"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:textSize="@dimen/text_size_12"
|
||||
android:gravity="end"
|
||||
android:layout_marginStart="@dimen/dimen_75_dp"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:textColor="@color/color_a6adb6" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:background="@color/color_f5f8fc" />
|
||||
</RelativeLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/divide_line2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_6_dp"
|
||||
android:background="@color/color_eff1f4" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_46_dp"
|
||||
android:paddingHorizontal="@dimen/dimen_20_dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="@string/add_black_list"
|
||||
android:textColor="@color/title_color"
|
||||
android:textSize="@dimen/text_size_16" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/sc_black_list"
|
||||
android:layout_width="@dimen/dimen_60_dp"
|
||||
android:layout_height="@dimen/dimen_28_dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:thumb="@drawable/switch_thumb_selector"
|
||||
app:track="@drawable/switch_track_selector" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:background="@color/color_f5f8fc" />
|
||||
</RelativeLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/divide_line3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_6_dp"
|
||||
android:background="@color/color_eff1f4" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_chat"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="@string/chat"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
android:textColor="@color/color_337eff"
|
||||
android:paddingVertical="@dimen/dimen_14_dp" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dimen_1_dp"
|
||||
android:background="@color/color_f5f8fc" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_delete"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="@string/delete_friend"
|
||||
android:textSize="@dimen/text_size_16"
|
||||
android:textColor="@color/color_e6605c"
|
||||
android:paddingVertical="@dimen/dimen_14_dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
BIN
contactkit-ui/src/main/res/mipmap/default_head_img.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
contactkit-ui/src/main/res/mipmap/ic_agree_status.png
Normal file
|
After Width: | Height: | Size: 526 B |
BIN
contactkit-ui/src/main/res/mipmap/ic_back.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
contactkit-ui/src/main/res/mipmap/ic_contact_black_list.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
contactkit-ui/src/main/res/mipmap/ic_contact_my_computer.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
contactkit-ui/src/main/res/mipmap/ic_contact_my_group.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
contactkit-ui/src/main/res/mipmap/ic_contact_verfiy_msg.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
contactkit-ui/src/main/res/mipmap/ic_group_defaulthead.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
contactkit-ui/src/main/res/mipmap/ic_grouphead_setting.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
BIN
contactkit-ui/src/main/res/mipmap/ic_nodate.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
contactkit-ui/src/main/res/mipmap/ic_reject_status.png
Normal file
|
After Width: | Height: | Size: 547 B |
BIN
contactkit-ui/src/main/res/mipmap/ic_search.png
Normal file
|
After Width: | Height: | Size: 516 B |
BIN
contactkit-ui/src/main/res/mipmap/ic_search_edit.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
contactkit-ui/src/main/res/mipmap/ic_searchfriends_clear.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
contactkit-ui/src/main/res/mipmap/ic_title_bar_more.png
Normal file
|
After Width: | Height: | Size: 838 B |
158
contactkit-ui/src/main/res/values-en/strings.xml
Normal file
@@ -0,0 +1,158 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- contact list -->
|
||||
<string name="contact_title">Contacts</string>
|
||||
<string name="contact_list_verify_msg">Verifications</string>
|
||||
<string name="contact_list_black_list">Blacklist</string>
|
||||
<string name="contact_list_my_group">My Groups</string>
|
||||
<string name="contact_list_my_computer">My Computer</string>
|
||||
|
||||
<!-- add friend page-->
|
||||
<string name="add_friend_title">Add Contact</string>
|
||||
<string name="search_friend_title">Search Contact</string>
|
||||
<string name="add_friend_search_hint">Enter Account</string>
|
||||
<string name="add_friend_searchphone_hint">Please enter phone number</string>
|
||||
<string name="add_friend_searchid_hint">Enter your friend’s account</string>
|
||||
<string name="add_friend_search_empty_tips">No exist</string>
|
||||
|
||||
<!-- verify page -->
|
||||
<string name="contact_verify_agree">Approve</string>
|
||||
<string name="contact_verify_reject">Reject</string>
|
||||
<string name="contact_verify_agreed">Approved</string>
|
||||
<string name="contact_verify_rejected"> Rejected</string>
|
||||
<string name="contact_verify_expired"> Expired</string>
|
||||
<string name="friend_apply">Friend Request</string>
|
||||
<string name="invited_to_join_group">invite you to groups %s</string>
|
||||
<string name="apply_to_join_group">Apply to join group%s</string>
|
||||
<string name="accept_your_friend_apply">Approved your apply</string>
|
||||
<string name="direct_add_your_friend_apply">add your contact</string>
|
||||
<string name="reject_your_friend_apply">reject your apply</string>
|
||||
<string name="verify_msg">Verification Message</string>
|
||||
<string name="activity_msg">Push Notification</string>
|
||||
<string name="verify_max_count_text">99+</string>
|
||||
<string name="verify_agree_message_text">Nice to meet you,let\'s chat</string>
|
||||
<string name="verify_empty_text">Verifications Empty</string>
|
||||
|
||||
<!-- my team page -->
|
||||
<string name="my_team">My Groups</string>
|
||||
|
||||
<!-- black page -->
|
||||
<string name="black_list">Blacklist</string>
|
||||
<string name="black_list_tips">After blocking a friend, you will no longer receive messages from the other party. To contact a blocked account, please unblock it first. </string>
|
||||
<string name="contact_black_list_relieve">Release</string>
|
||||
<string name="add_black_error">%s Failed to block</string>
|
||||
|
||||
<!-- userinfo page -->
|
||||
<string name="clear_all">Clear</string>
|
||||
<string name="birthday">Birthday</string>
|
||||
<string name="phone">Mobile</string>
|
||||
<string name="email">Mail</string>
|
||||
<string name="personal_signature">What’s up</string>
|
||||
<string name="comment_name">Nick Name</string>
|
||||
<string name="notify_message">Message Notification</string>
|
||||
<string name="add_black_list">Block</string>
|
||||
<string name="chat">Chat</string>
|
||||
<string name="delete_friend">Delete Contact</string>
|
||||
<string name="add_friend">添加好友</string>
|
||||
<string name="contact_user_info_account">Account:%s</string>
|
||||
<string name="contact_user_info_nickname">Nick Name:%s</string>
|
||||
<string name="delete_contact_account">Dlete “%s”</string>
|
||||
<string name="save">Save</string>
|
||||
<string name="add_friend_operate_success">Sent Contact apply</string>
|
||||
<string name="add_friend_operate_fail">Failed to apply contact %s</string>
|
||||
|
||||
<!--添加好友页面 -->
|
||||
<string name="add_friend_search_error">Failed to search</string>
|
||||
<string name="add_friend_search_result">Add</string>
|
||||
|
||||
<!-- error toast -->
|
||||
<string name="agree_add_friend_fail">Failed</string>
|
||||
<string name="disagree_add_friend_fail">Failed</string>
|
||||
<string name="agree_apply_join_team_fail">Failed</string>
|
||||
<string name="disagree_apply_join_team_fail">Failed</string>
|
||||
<string name="agree_invite_team_fail">Failed</string>
|
||||
<string name="disagree_invite_team_fail">Failed</string>
|
||||
|
||||
<string name="remove_black_fail">Failed to remove blacklist</string>
|
||||
<string name="verify_duplicate_fail">Already done on other devices</string>
|
||||
|
||||
<!-- selector-->
|
||||
<string name="select">Select Friends</string>
|
||||
<!-- <string name="selector_sure">Yes(%d)</string>-->
|
||||
<string name="selector_sure">Next</string>
|
||||
<string name="invite_sure">invite</string>
|
||||
<!-- <string name="selector_sure_without_num">Yes</string>-->
|
||||
<string name="selector_sure_without_num">Next</string>
|
||||
<string name="contact_selector_max_count">select up to %s friends</string>
|
||||
<string name="contact_selector_over_count">exceeding the maximum capacity</string>
|
||||
<string name="selector_friend_empty">No Member</string>
|
||||
<string name="selector_group_empty">No Group</string>
|
||||
<string name="select_empty_tips">No Member</string>
|
||||
<string name="fun_selector_close">Close</string>
|
||||
<string name="fun_contact_search">Search</string>
|
||||
|
||||
<!-- search -->
|
||||
|
||||
<string name="global_search_hint"> Please enter username/group chat name keyword</string>
|
||||
<string name="global_search_title">Search</string>
|
||||
<string name="global_searchfriend_title">Search Friends</string>
|
||||
|
||||
<string name="global_search_friend_title">Contacts</string>
|
||||
<string name="global_search_group_title">Temperature Group</string>
|
||||
<string name="global_search_team_title">Group</string>
|
||||
<string name="global_search_empty">No exist</string>
|
||||
|
||||
<!-- common-->
|
||||
<string name="cancel"> Cancel </string>
|
||||
<string name="contact_network_error_tip">No Internet</string>
|
||||
<string name="contact_hint">You haven\'t talked about it yet~</string>
|
||||
|
||||
|
||||
<string name="fun_contact_search_hint_text">Search</string>
|
||||
<string name="fun_contact_searchresult_text">Home Page</string>
|
||||
<string name="fun_contact_searchresult_addtext">Add To</string>
|
||||
<string name="fun_contact_searchself_txt">Cannot add your own account as a friend! </string>
|
||||
<string name="fun_contact_searchfriends_txt">You are already friends! </string>
|
||||
<string name="fun_contact_addfriends_verifymsg">Fill in the verification information</string>
|
||||
<string name="fun_contact_verifymsg_tips">Please enter verification information</string>
|
||||
<string name="fun_contact_addfriends_remarks">Remarks</string>
|
||||
<string name="fun_contact_remarks_tips">Please enter remarks</string>
|
||||
<string name="fun_contact_addfriends_send">Send</string>
|
||||
<string name="fun_contact_createteam_tips">Search using name</string>
|
||||
<string name="fun_creategroup_members">Member %d</string>
|
||||
<string name="fun_creategroup_uploadhead">Upload avatar</string>
|
||||
<string name="fun_creategroup_autojoin_tips">Users will join the group after receiving the invitation. After turning off this setting, requiring members to join the group requires manual acceptance of the invitation. </string>
|
||||
<string name="fun_creategroup_autojoin">User automatically joins</string>
|
||||
<string name="fun_creategroup_name">Group name</string>
|
||||
<string name="fun_creategroup_title">Set group file</string>
|
||||
<string name="fun_creategroup_sure">Create</string>
|
||||
<string name="fun_contactselector_last">Latest Contact %d</string>
|
||||
<string name="fun_contactselector_mylove">Special attention %d</string>
|
||||
<string name="fun_contactselector_members">All friends %d</string>
|
||||
<string name="fun_contactselector_result">Find results</string>
|
||||
<string name="fun_verifymsg">Verification information</string>
|
||||
<string name="fun_specialgz_txt">Special attention</string>
|
||||
<string name="fun_searchresult_txt">Search results</string>
|
||||
<string name="fun_addmembers_txt">New</string>
|
||||
<string name="fun_addmemberstoast_txt">Keep at least one friend</string>
|
||||
<string name="fun_contactselector_teamqr">QR code</string>
|
||||
<string name="fun_contactselector_teamurl">Invitation URL</string>
|
||||
<string name="nmhmylg_txt">You haven\'t talked about it yet~</string>
|
||||
<string name="voom_message_txt">[Short video message]</string>
|
||||
<string name="gerenminp_txt">[Business Card]</string>
|
||||
<string name="zhuanzhang_chat_txt">[Transfer]</string>
|
||||
<string name="hongbao_chat_txt">[Red envelope]</string>
|
||||
<string name="albums_chat_txt">[Albums]</string>
|
||||
<string name="helppay_chat_txt">[Help with Payment]</string>
|
||||
<string name="inviteGroup_chat_txt">[Invite to Group]</string>
|
||||
<string name="custom_chat_txt">[Custom Message]</string>
|
||||
<string name="removeblack_txt">Unblock</string>
|
||||
<string name="teamdissmiss_txt">This group has been disbanded</string>
|
||||
<string name="teamjoined_txt">You are already in this group</string>
|
||||
<string name="know_txt">I see</string>
|
||||
<string name="nodate_txt">No data</string>
|
||||
</resources>
|
||||
160
contactkit-ui/src/main/res/values-ja/strings.xml
Normal file
@@ -0,0 +1,160 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<!-- 連絡先リスト -->
|
||||
<string name="contact_title">連絡帳</string>
|
||||
<string name="contact_list_verify_msg">確認メッセージ</string>
|
||||
<string name="contact_list_black_list">ブラックリスト</string>
|
||||
<string name="contact_list_my_group">グループ チャット</string>
|
||||
<string name="contact_list_my_computer">私のコンピュータ</string>
|
||||
|
||||
<!-- 友達ページを追加 -->
|
||||
<string name="add_friend_title">友達を追加</string>
|
||||
<string name="search_friend_title">友達を検索</string>
|
||||
<string name="add_friend_search_hint">アカウント番号を入力してください</string>
|
||||
<string name="add_friend_searchphone_hint">携帯電話番号を入力してください</string>
|
||||
<string name="add_friend_searchid_hint">友達のアカウントを入力してください</string>
|
||||
<string name="add_friend_search_empty_tips">このユーザーは存在しません</string>
|
||||
|
||||
<!-- ページを確認 -->
|
||||
<string name="contact_verify_agree">同意する</string>
|
||||
<string name="contact_verify_reject">拒否</string>
|
||||
<string name="contact_verify_agreed">同意しました</string>
|
||||
<string name="contact_verify_rejected">拒否されました</string>
|
||||
<string name="contact_verify_expired">期限切れ</string>
|
||||
<string name="friend_apply">友達申請</string>
|
||||
<string name="invited_to_join_group">グループに招待します %s</string>
|
||||
<string name="apply_to_join_group">%s グループへの参加を申請</string>
|
||||
<string name="accept_your_friend_apply">友達リクエストを承認しました</string>
|
||||
<string name="direct_add_your_friend_apply">あなたを友達として直接追加します</string>
|
||||
<string name="reject_your_friend_apply">友達リクエストを拒否しました</string>
|
||||
<string name="verify_msg">確認メッセージ</string>
|
||||
<string name="activity_msg">プッシュ通知</string>
|
||||
<string name="verify_max_count_text">99+</string>
|
||||
<string name="verify_agree_message_text">あなたの申請に同意しました。今すぐチャットを始めましょう~</string>
|
||||
<string name="verify_empty_text">友達申請情報がありません</string>
|
||||
|
||||
<!-- 私のチーム ページ -->
|
||||
<string name="my_team">私のグループ チャット</string>
|
||||
|
||||
<!-- 黒いページ -->
|
||||
<string name="black_list">ブラックリスト</string>
|
||||
<string name="black_list_tips">友達をブロックすると、相手からメッセージを受信できなくなります。 ブロックされたアカウントに連絡するには、まずブロックを解除してください。 </string>
|
||||
<string name="contact_black_list_relieve">リリース</string>
|
||||
<string name="add_black_error">%s をブラックリストに追加できませんでした</string>
|
||||
|
||||
<!-- ユーザー情報ページ -->
|
||||
<string name="clear_all">クリア</string>
|
||||
<string name="birthday">誕生日</string>
|
||||
<string name="phone">携帯電話</string>
|
||||
<string name="email">メール</string>
|
||||
<string name="personal_signature">個人の署名</string>
|
||||
<string name="comment_name">コメント名</string>
|
||||
|
||||
<string name="notify_message">メッセージ通知</string>
|
||||
<string name="add_black_list">ブラックリストに追加</string>
|
||||
<string name="chat">チャット</string>
|
||||
<string name="delete_friend">友達を削除</string>
|
||||
<string name="add_friend">友達を追加</string>
|
||||
<string name="contact_user_info_account">アカウント:%s</string>
|
||||
<string name="contact_user_info_nickname">ニックネーム:%s</string>
|
||||
<string name="delete_contact_account">連絡先「%s」を削除</string>
|
||||
<string name="save">保存</string>
|
||||
<string name="add_friend_operate_success">正常に送信されました。友達の確認を待っています</string>
|
||||
<string name="add_friend_operate_fail">送信に失敗しました %s</string>
|
||||
|
||||
<!-- 友達ページを追加 -->
|
||||
<string name="add_friend_search_error">検索に失敗しました</string>
|
||||
<string name="add_friend_search_result">新規</string>
|
||||
|
||||
|
||||
<!-- トーストエラー -->
|
||||
<string name="agree_add_friend_fail">友達申請に同意できませんでした</string>
|
||||
<string name="disagree_add_friend_fail">友達申請を拒否できませんでした</string>
|
||||
<string name="agree_apply_join_team_fail">チームへの参加に同意できませんでした</string>
|
||||
<string name="disagree_apply_join_team_fail">グループ申請を拒否できませんでした</string>
|
||||
<string name="agree_invite_team_fail">グループへの招待に同意できませんでした</string>
|
||||
<string name="disagree_invite_team_fail">グループへの招待を拒否できませんでした</string>
|
||||
<string name="remove_black_fail">ブラックリストの削除に失敗しました</string>
|
||||
<string name="verify_duplicate_fail">確認メッセージは相手側で処理されました</string>
|
||||
|
||||
<!-- セレクター-->
|
||||
<string name="select">友達を選択</string>
|
||||
<!-- <string name="selector_sure">確認(%d)</string>-->
|
||||
<string name="selector_sure">次のステップ</string>
|
||||
<string name="invite_sure">招待</string>
|
||||
<!-- <string name="selector_sure_without_num">OK</string>-->
|
||||
<string name="selector_sure_without_num">次のステップ</string>
|
||||
<string name="contact_selector_max_count">最大 %s 人の友達を選択します</string>
|
||||
<string name="contact_selector_over_count">人数制限を超えています</string>
|
||||
<string name="selector_friend_empty">まだ友達がいません</string>
|
||||
<string name="selector_group_empty">グループ チャットなし</string>
|
||||
<string name="select_empty_tips">連絡先を選択してください</string>
|
||||
<string name="fun_selector_close">閉じる</string>
|
||||
<string name="fun_contact_search">検索</string>
|
||||
|
||||
<!-- 検索 -->
|
||||
<string name="global_search_hint">ユーザー名/グループチャット名のキーワードを入力してください</string>
|
||||
<string name="global_search_title">検索</string>
|
||||
<string name="global_searchfriend_title">友達を検索</string>
|
||||
|
||||
<string name="global_search_friend_title">友達</string>
|
||||
<string name="global_search_group_title">ディスカッション グループ</string>
|
||||
<string name="global_search_team_title">グループ</string>
|
||||
<string name="global_search_empty">このユーザーは存在しません</string>
|
||||
|
||||
<!-- 共通-->
|
||||
<string name="cancel">キャンセル</string>
|
||||
<string name="contact_network_error_tip">ネットワークは現在利用できません。ネットワーク設定を確認してください。 </string>
|
||||
|
||||
<string name="contact_hint">まだ話していませんね~</string>
|
||||
|
||||
<string name="fun_contact_search_hint_text">検索</string>
|
||||
<string name="fun_contact_searchresult_text">ホームページ</string>
|
||||
<string name="fun_contact_searchresult_addtext">に追加</string>
|
||||
<string name="fun_contact_searchself_txt">自分のアカウントを友達として追加できません。 </string>
|
||||
<string name="fun_contact_searchfriends_txt">あなたはすでに友達です! </string>
|
||||
<string name="fun_contact_addfriends_verifymsg">確認情報を入力してください</string>
|
||||
<string name="fun_contact_verifymsg_tips">確認情報を入力してください</string>
|
||||
<string name="fun_contact_addfriends_remarks">備考</string>
|
||||
<string name="fun_contact_remarks_tips">備考を入力してください</string>
|
||||
<string name="fun_contact_addfriends_send">送信</string>
|
||||
<string name="fun_contact_createteam_tips">名前で検索</string>
|
||||
<string name="fun_creategroup_members">メンバー %d</string>
|
||||
<string name="fun_creategroup_uploadhead">アバターをアップロード</string>
|
||||
<string name="fun_creategroup_autojoin_tips">ユーザーは、招待を受信した後にグループに参加します。この設定をオフにした後、メンバーにグループへの参加を要求するには、招待を手動で承諾する必要があります。 </string>
|
||||
<string name="fun_creategroup_autojoin">ユーザーは自動的に参加します</string>
|
||||
<string name="fun_creategroup_name">グループ名</string>
|
||||
<string name="fun_creategroup_title">グループ ファイルを設定する</string>
|
||||
<string name="fun_creategroup_sure">作成</string>
|
||||
<string name="fun_contactselector_last">最新の連絡先 %d</string>
|
||||
<string name="fun_contactselector_mylove">特別な注意 %d</string>
|
||||
<string name="fun_contactselector_members">友達全員 %d</string>
|
||||
<string name="fun_contactselector_result">検索結果</string>
|
||||
<string name="fun_contactselector_teamqr">QR コード</string>
|
||||
<string name="fun_contactselector_teamurl">招待 URL</string>
|
||||
<string name="fun_verifymsg">検証情報</string>
|
||||
<string name="fun_specialgz_txt">特別な注意</string>
|
||||
<string name="fun_searchresult_txt">検索結果</string>
|
||||
<string name="fun_addmembers_txt">新規</string>
|
||||
<string name="fun_addmemberstoast_txt">少なくとも 1 人の友達を維持してください</string>
|
||||
<string name="nmhmylg_txt">まだ話していませんね~</string>
|
||||
<string name="voom_message_txt">[短いビデオと音声メッセージ]</string>
|
||||
<string name="gerenminp_txt">[名刺]</string>
|
||||
<string name="zhuanzhang_chat_txt">[転送]</string>
|
||||
<string name="hongbao_chat_txt">[红包]</string>
|
||||
<string name="albums_chat_txt">[アルバム]</string>
|
||||
<string name="helppay_chat_txt">[支払いを手伝う]</string>
|
||||
<string name="inviteGroup_chat_txt">[グループへの招待]</string>
|
||||
<string name="custom_chat_txt">[カスタム メッセージ]</string>
|
||||
<string name="removeblack_txt">ブロックを解除する</string>
|
||||
<string name="teamdissmiss_txt">このグループは解散しました</string>
|
||||
<string name="teamjoined_txt">あなたはすでにこのグループに属しています</string>
|
||||
<string name="know_txt">なるほど</string>
|
||||
<string name="nodate_txt">まだ情報がありません</string>
|
||||
|
||||
</resources>
|
||||
159
contactkit-ui/src/main/res/values-zh/strings.xml
Normal file
@@ -0,0 +1,159 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<!-- contact list -->
|
||||
<string name="contact_title">通讯录</string>
|
||||
<string name="contact_list_verify_msg">验证消息</string>
|
||||
<string name="contact_list_black_list">黑名单</string>
|
||||
<string name="contact_list_my_group">我的群聊</string>
|
||||
<string name="contact_list_my_computer">我的电脑</string>
|
||||
|
||||
<!-- add friend page-->
|
||||
<string name="add_friend_title">添加好友</string>
|
||||
<string name="search_friend_title">搜索好友</string>
|
||||
<string name="add_friend_search_hint">请输入账号</string>
|
||||
<string name="add_friend_searchphone_hint">请输入手机号</string>
|
||||
<string name="add_friend_searchid_hint">输入好友的账号</string>
|
||||
<string name="add_friend_search_empty_tips">该用户不存在</string>
|
||||
|
||||
<!-- verify page -->
|
||||
<string name="contact_verify_agree">同意</string>
|
||||
<string name="contact_verify_reject">拒绝</string>
|
||||
<string name="contact_verify_agreed">已同意</string>
|
||||
<string name="contact_verify_rejected">已拒绝</string>
|
||||
<string name="contact_verify_expired">已过期</string>
|
||||
<string name="friend_apply">好友申请</string>
|
||||
<string name="invited_to_join_group">邀请你加入群 %s</string>
|
||||
<string name="apply_to_join_group">申请加入%s群</string>
|
||||
<string name="accept_your_friend_apply">同意了你的好友请求</string>
|
||||
<string name="direct_add_your_friend_apply">直接添加你为好友</string>
|
||||
<string name="reject_your_friend_apply">拒绝了你的好友请求</string>
|
||||
<string name="verify_msg">验证消息</string>
|
||||
<string name="activity_msg">推送通知</string>
|
||||
<string name="verify_max_count_text">99+</string>
|
||||
<string name="verify_agree_message_text">我已经同意了你的申请,现在开始聊天吧~</string>
|
||||
<string name="verify_empty_text">暂无好友申请信息</string>
|
||||
|
||||
<!-- my team page -->
|
||||
<string name="my_team">我的群聊</string>
|
||||
|
||||
<!-- black page -->
|
||||
<string name="black_list">黑名单</string>
|
||||
<string name="black_list_tips">屏蔽好友后,将不会再收到对方消息。要联系已屏蔽的账号,请先解除屏蔽。</string>
|
||||
<string name="contact_black_list_relieve">解除</string>
|
||||
<string name="add_black_error">%s加入黑名单失败</string>
|
||||
|
||||
<!-- userinfo page -->
|
||||
<string name="clear_all">清空</string>
|
||||
<string name="birthday">生日</string>
|
||||
<string name="phone">手机</string>
|
||||
<string name="email">邮箱</string>
|
||||
<string name="personal_signature">个性签名</string>
|
||||
<string name="comment_name">备注名</string>
|
||||
|
||||
<string name="notify_message">消息通知</string>
|
||||
<string name="add_black_list">加入黑名单</string>
|
||||
<string name="chat">聊天</string>
|
||||
<string name="delete_friend">删除好友</string>
|
||||
<string name="add_friend">添加好友</string>
|
||||
<string name="contact_user_info_account">账号:%s</string>
|
||||
<string name="contact_user_info_nickname">昵称:%s</string>
|
||||
<string name="delete_contact_account">将联系人“%s”删除</string>
|
||||
<string name="save">保存</string>
|
||||
<string name="add_friend_operate_success">发送成功,等待好友验证</string>
|
||||
<string name="add_friend_operate_fail">发送失败 %s</string>
|
||||
|
||||
<!--添加好友页面 -->
|
||||
<string name="add_friend_search_error">搜索失败</string>
|
||||
<string name="add_friend_search_result">添加</string>
|
||||
|
||||
|
||||
<!-- error toast -->
|
||||
<string name="agree_add_friend_fail">同意好友申请失败</string>
|
||||
<string name="disagree_add_friend_fail">拒绝好友申请失败</string>
|
||||
<string name="agree_apply_join_team_fail">同意入群申请失败</string>
|
||||
<string name="disagree_apply_join_team_fail">拒绝入群申请失败</string>
|
||||
<string name="agree_invite_team_fail">同意入群邀请失败</string>
|
||||
<string name="disagree_invite_team_fail">拒绝入群邀请失败</string>
|
||||
<string name="remove_black_fail">黑名单移除失败</string>
|
||||
<string name="verify_duplicate_fail">该验证消息已在其他端处理</string>
|
||||
|
||||
<!-- selector-->
|
||||
<string name="select">选择好友</string>
|
||||
<!-- <string name="selector_sure">确定(%d)</string>-->
|
||||
<string name="selector_sure">下一步</string>
|
||||
<string name="invite_sure">邀请</string>
|
||||
<!-- <string name="selector_sure_without_num">确定</string>-->
|
||||
<string name="selector_sure_without_num">下一步</string>
|
||||
<string name="contact_selector_max_count">最多选择%s个好友</string>
|
||||
<string name="contact_selector_over_count">超出人数限制</string>
|
||||
<string name="selector_friend_empty">暂无好友</string>
|
||||
<string name="selector_group_empty">暂无群聊</string>
|
||||
<string name="select_empty_tips">请选择联系人</string>
|
||||
<string name="fun_selector_close">关闭</string>
|
||||
<string name="fun_contact_search">搜索</string>
|
||||
|
||||
<!-- search -->
|
||||
<string name="global_search_hint">请输入用户名/群聊名关键字</string>
|
||||
<string name="global_search_title">搜索</string>
|
||||
<string name="global_searchfriend_title">搜索好友</string>
|
||||
|
||||
<string name="global_search_friend_title">好友</string>
|
||||
<string name="global_search_group_title">讨论组</string>
|
||||
<string name="global_search_team_title">群組</string>
|
||||
<string name="global_search_empty">该用户不存在</string>
|
||||
|
||||
<!-- common-->
|
||||
<string name="cancel">取消</string>
|
||||
<string name="contact_network_error_tip">当前网络不可用,请检查你当网络设置。</string>
|
||||
|
||||
<string name="contact_hint">你们还没有聊过哦~</string>
|
||||
|
||||
<string name="fun_contact_search_hint_text">搜索</string>
|
||||
<string name="fun_contact_searchresult_text">主页</string>
|
||||
<string name="fun_contact_searchresult_addtext">添加</string>
|
||||
<string name="fun_contact_searchself_txt">无法添加自己的账号为好友哦!</string>
|
||||
<string name="fun_contact_searchfriends_txt">你们已经是好友了哦!</string>
|
||||
<string name="fun_contact_addfriends_verifymsg">填写验证信息</string>
|
||||
<string name="fun_contact_verifymsg_tips">请输入验证信息</string>
|
||||
<string name="fun_contact_addfriends_remarks">备注</string>
|
||||
<string name="fun_contact_remarks_tips">请输入备注</string>
|
||||
<string name="fun_contact_addfriends_send">发送</string>
|
||||
<string name="fun_contact_createteam_tips">使用名称进行搜索</string>
|
||||
<string name="fun_creategroup_members">成员 %d</string>
|
||||
<string name="fun_creategroup_uploadhead">上传头像</string>
|
||||
<string name="fun_creategroup_autojoin_tips">用户在收到邀请后就会加入群组,关闭此设定后要求成员加入群组需手动接受邀请。</string>
|
||||
<string name="fun_creategroup_autojoin">用户自动加入</string>
|
||||
<string name="fun_creategroup_name">群组名称</string>
|
||||
<string name="fun_creategroup_title">设定群组档案</string>
|
||||
<string name="fun_creategroup_sure">建立</string>
|
||||
<string name="fun_contactselector_last">最近联系 %d</string>
|
||||
<string name="fun_contactselector_mylove">特别关注 %d</string>
|
||||
<string name="fun_contactselector_members">全部好友 %d</string>
|
||||
<string name="fun_contactselector_result">查找结果</string>
|
||||
<string name="fun_verifymsg">验证信息</string>
|
||||
<string name="fun_specialgz_txt">特别关注</string>
|
||||
<string name="fun_searchresult_txt">查找结果</string>
|
||||
<string name="fun_addmembers_txt">新增</string>
|
||||
<string name="fun_addmemberstoast_txt">最少保留一位好友</string>
|
||||
<string name="fun_contactselector_teamqr">行动码</string>
|
||||
<string name="fun_contactselector_teamurl">邀请网址</string>
|
||||
<string name="nmhmylg_txt">你们还没有聊过哦~</string>
|
||||
<string name="voom_message_txt">[短影音消息]</string>
|
||||
<string name="gerenminp_txt">[名片]</string>
|
||||
<string name="zhuanzhang_chat_txt">[转账]</string>
|
||||
<string name="hongbao_chat_txt">[红包]</string>
|
||||
<string name="albums_chat_txt">[相册]</string>
|
||||
<string name="helppay_chat_txt">[帮忙代付]</string>
|
||||
<string name="inviteGroup_chat_txt">[邀请进群]</string>
|
||||
<string name="custom_chat_txt">[自定义消息]</string>
|
||||
<string name="removeblack_txt">解除屏蔽</string>
|
||||
<string name="teamdissmiss_txt">该群已被解散</string>
|
||||
<string name="teamjoined_txt">您已经在该群组中</string>
|
||||
<string name="know_txt">我知道了</string>
|
||||
<string name="nodate_txt">暂无数据</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<declare-styleable name="ContactListView">
|
||||
|
||||
<attr name="nameTextColor" format="color" />
|
||||
<attr name="nameTextSize" format="dimension" />
|
||||
<attr name="indexTextColor" format="color" />
|
||||
<attr name="indexTextSize" format="dimension" />
|
||||
<attr name="divideLineColor" format="color" />
|
||||
<attr name="showIndexBar" format="boolean" />
|
||||
<attr name="showTopPin" format="boolean" />
|
||||
<attr name="showSelector" format="boolean" />
|
||||
<attr name="avatarCornerRadius" format="dimension" />
|
||||
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
17
contactkit-ui/src/main/res/values/attrs_index_bar.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<declare-styleable name="IndexBar">
|
||||
<attr name="indexBarTextSize" format="dimension" />
|
||||
<attr name="indexBarTextColor" format="color" />
|
||||
<attr name="indexBarTextColorPress" format="color" />
|
||||
<attr name="indexBarPressBackground" format="color" />
|
||||
</declare-styleable>
|
||||
|
||||
|
||||
</resources>
|
||||
23
contactkit-ui/src/main/res/values/attrs_title_bar.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<declare-styleable name="TitleBarView">
|
||||
|
||||
<attr name="head_img_src" format="integer" />
|
||||
<attr name="head_img_visible" format="enum">
|
||||
<enum name="visible" value="0"/>
|
||||
<enum name="invisible" value="4"/>
|
||||
<enum name="gone" value="8"/>
|
||||
</attr>
|
||||
<attr name="right_img_src" format="integer"/>
|
||||
<attr name="right_img_second_src" format="integer"/>
|
||||
<attr name="head_title" format="string"/>
|
||||
<attr name="head_title_color" format="color"/>
|
||||
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
52
contactkit-ui/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<color name="title_color">#333333</color>
|
||||
<color name="color_14131b">#ff14131b</color>
|
||||
<color name="color_ffffff">#ffffffff</color>
|
||||
<color name="color_f5f8fc">#F5F8FC</color>
|
||||
<color name="color_e5e5e5">#E5E5E5</color>
|
||||
<color name="color_58be6b">#58BE6B</color>
|
||||
<color name="color_ededed">#ededed</color>
|
||||
<color name="color_f7f7f7">#F7F7F7</color>
|
||||
<color name="color_525c8c">#525C8C</color>
|
||||
<color name="color_537ff4">#537FF4</color>
|
||||
<color name="color_f2f4f5">#F2F4F5</color>
|
||||
<color name="color_337eff">#337EFF</color>
|
||||
<color name="color_b3b7bc">#B3B7BC</color>
|
||||
<color name="color_d9d9d9">#D9D9D9</color>
|
||||
<color name="color_666666">#666666</color>
|
||||
<color name="color_a6adb6">#A6ADB6</color>
|
||||
<color name="color_e6605c">#E6605C</color>
|
||||
<color name="color_eff1f4">#EFF1F4</color>
|
||||
<color name="color_8f8f8f">#8F8F8F</color>
|
||||
<color name="color_929299">#929299</color>
|
||||
<color name="color_3eaf96">#3eaf96</color>
|
||||
<color name="color_4d000000">#4d000000</color>
|
||||
<color name="color_f24957">#f24957</color>
|
||||
<color name="color_ededef">#ededef</color>
|
||||
<color name="color_e9eff5">#e9eff5</color>
|
||||
<color name="color_dbdde4">#dbdde4</color>
|
||||
<color name="color_dbe0e8">#DBE0E8</color>
|
||||
<color name="title_transfer">#00000000</color>
|
||||
<color name="color_white">#FFFFFF</color>
|
||||
<color name="color_fe6881">#FE6881</color>
|
||||
<color name="color_eeeeee">#eeeeee</color>
|
||||
<color name="color_09bb07">#09BB07</color>
|
||||
<color name="color_fcfcfc">#FCFCFC</color>
|
||||
<color name="color_bcbcbc">#BCBCBC</color>
|
||||
<color name="color_d8d8d8">#D8D8D8</color>
|
||||
<color name="color_d4dbd6">#D4DBD6</color>
|
||||
<color name="color_7f7b81">#7F7B81</color>
|
||||
<color name="color_6877fe">#6877FE</color>
|
||||
<color name="color_6d80ff">#6d80ff</color>
|
||||
<color name="color_6d80ff_alpha70">#4d6D80FF</color> <!--透明度70-->
|
||||
<color name="color_999999">#999999</color> <!--透明度70-->
|
||||
<color name="color_6d94ff">#6d94ff</color>
|
||||
|
||||
|
||||
</resources>
|
||||
63
contactkit-ui/src/main/res/values/dimens.xml
Normal file
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<dimen name="page_margin_left_right">20dp</dimen>
|
||||
<dimen name="page_title_size">20dp</dimen>
|
||||
<dimen name="page_title_bar_height">60dp</dimen>
|
||||
<dimen name="image_operate_width_height">24dp</dimen>
|
||||
<dimen name="image_operate_margin">12dp</dimen>
|
||||
<dimen name="image_head_width_height">32dp</dimen>
|
||||
<dimen name="image_contact_width_height">36dp</dimen>
|
||||
|
||||
<dimen name="dimen_1_dp">1dp</dimen>
|
||||
<dimen name="dimen_3_dp">3dp</dimen>
|
||||
<dimen name="dimen_4_dp">4dp</dimen>
|
||||
<dimen name="dimen_5_dp">5dp</dimen>
|
||||
<dimen name="dimen_6_dp">6dp</dimen>
|
||||
<dimen name="dimen_7_dp">7dp</dimen>
|
||||
<dimen name="dimen_8_dp">8dp</dimen>
|
||||
<dimen name="dimen_9_dp">9dp</dimen>
|
||||
<dimen name="dimen_10_dp">10dp</dimen>
|
||||
<dimen name="dimen_12_dp">12dp</dimen>
|
||||
<dimen name="dimen_13_dp">13dp</dimen>
|
||||
<dimen name="dimen_14_dp">14dp</dimen>
|
||||
<dimen name="dimen_15_dp">15dp</dimen>
|
||||
<dimen name="dimen_16_dp">16dp</dimen>
|
||||
<dimen name="dimen_18_dp">18dp</dimen>
|
||||
<dimen name="dimen_20_dp">20dp</dimen>
|
||||
<dimen name="dimen_23_dp">23dp</dimen>
|
||||
<dimen name="dimen_24_dp">24dp</dimen>
|
||||
<dimen name="dimen_25_dp">25dp</dimen>
|
||||
<dimen name="dimen_26_dp">26dp</dimen>
|
||||
<dimen name="dimen_28_dp">28dp</dimen>
|
||||
<dimen name="dimen_32_dp">32dp</dimen>
|
||||
<dimen name="dimen_42_dp">42dp</dimen>
|
||||
<dimen name="dimen_46_dp">46dp</dimen>
|
||||
<dimen name="dimen_52_dp">52dp</dimen>
|
||||
<dimen name="dimen_55_dp">55dp</dimen>
|
||||
<dimen name="dimen_56_dp">56dp</dimen>
|
||||
<dimen name="dimen_60_dp">60dp</dimen>
|
||||
<dimen name="dimen_64_dp">64dp</dimen>
|
||||
<dimen name="dimen_88_dp">64dp</dimen>
|
||||
<dimen name="dimen_100_dp">100dp</dimen>
|
||||
<dimen name="dimen_115_dp">115dp</dimen>
|
||||
<dimen name="dimen_118_dp">118dp</dimen>
|
||||
<dimen name="verify_name_max_len">120dp</dimen>
|
||||
<dimen name="dimen_163_dp">163dp</dimen>
|
||||
<dimen name="dimen_188_dp">188dp</dimen>
|
||||
<dimen name="verify_action_max_len">200dp</dimen>
|
||||
|
||||
<dimen name="text_size_8">8sp</dimen>
|
||||
<dimen name="text_size_11">11sp</dimen>
|
||||
<dimen name="text_size_12">12sp</dimen>
|
||||
<dimen name="text_size_13">13sp</dimen>
|
||||
<dimen name="text_size_14">14sp</dimen>
|
||||
<dimen name="text_size_16">16sp</dimen>
|
||||
<dimen name="text_size_18">18sp</dimen>
|
||||
<dimen name="text_size_22">22sp</dimen>
|
||||
</resources>
|
||||
162
contactkit-ui/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,162 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
~ Use of this source code is governed by a MIT license that can be
|
||||
~ found in the LICENSE file.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<!-- contact list -->
|
||||
<string name="contact_title">通訊錄</string>
|
||||
<string name="contact_list_verify_msg">驗證訊息</string>
|
||||
<string name="contact_list_black_list">黑名單</string>
|
||||
<string name="contact_list_my_group">我的群組聊天</string>
|
||||
<string name="contact_list_my_computer">我的電腦</string>
|
||||
|
||||
<!-- add friend page-->
|
||||
<string name="add_friend_title">新增好友</string>
|
||||
<string name="search_friend_title">搜尋好友</string>
|
||||
<string name="add_friend_search_hint">請輸入帳號</string>
|
||||
<string name="add_friend_searchphone_hint">請輸入手機號碼</string>
|
||||
<string name="add_friend_searchid_hint">輸入好友的帳號</string>
|
||||
<string name="add_friend_search_empty_tips">該使用者不存在</string>
|
||||
|
||||
<!-- verify page -->
|
||||
<string name="contact_verify_agree">同意</string>
|
||||
<string name="contact_verify_reject">拒絕</string>
|
||||
<string name="contact_verify_agreed">已同意</string>
|
||||
<string name="contact_verify_rejected">已拒絕</string>
|
||||
<string name="contact_verify_expired">已過期</string>
|
||||
<string name="friend_apply">好友申請</string>
|
||||
<string name="invited_to_join_group">邀請你加入群組 %s</string>
|
||||
<string name="apply_to_join_group">申請加入%s群</string>
|
||||
<string name="accept_your_friend_apply">同意了你的好友請求</string>
|
||||
<string name="direct_add_your_friend_apply">直接加入你為好友</string>
|
||||
<string name="reject_your_friend_apply">拒絕了你的好友請求</string>
|
||||
<string name="verify_msg">驗證訊息</string>
|
||||
<string name="activity_msg">推送通知</string>
|
||||
<string name="verify_max_count_text">99+</string>
|
||||
<string name="verify_agree_message_text">我已經同意了你的申請,現在開始聊天吧~</string>
|
||||
<string name="verify_empty_text">暫無好友申請資料</string>
|
||||
|
||||
<!-- my team page -->
|
||||
<string name="my_team">我的群組聊天</string>
|
||||
|
||||
<!-- black page -->
|
||||
<string name="black_list">黑名單</string>
|
||||
<string name="black_list_tips">封鎖好友後,將不會再收到對方訊息。若要聯絡已封鎖的帳號,請先解除封鎖。</string>
|
||||
<string name="contact_black_list_relieve">解除</string>
|
||||
<string name="add_black_error">%s加入黑名單失敗</string>
|
||||
|
||||
<!-- userinfo page -->
|
||||
<string name="clear_all">清空</string>
|
||||
<string name="birthday">生日</string>
|
||||
<string name="phone">手機</string>
|
||||
<string name="email">郵箱</string>
|
||||
<string name="personal_signature">個性簽名</string>
|
||||
<string name="comment_name">備註名稱</string>
|
||||
|
||||
<string name="notify_message">訊息通知</string>
|
||||
<string name="add_black_list">加入黑名單</string>
|
||||
<string name="chat">聊天</string>
|
||||
<string name="delete_friend">刪除好友</string>
|
||||
<string name="add_friend">新增好友</string>
|
||||
<string name="contact_user_info_account">帳號:%s</string>
|
||||
<string name="contact_user_info_nickname">暱稱:%s</string>
|
||||
<string name="delete_contact_account">將聯絡人「%s」刪除</string>
|
||||
<string name="save">儲存</string>
|
||||
<string name="add_friend_operate_success">發送成功,等待好友驗證</string>
|
||||
<string name="add_friend_operate_fail">傳送失敗 %s</string>
|
||||
|
||||
<!--新增好友頁面 -->
|
||||
<string name="add_friend_search_error">搜尋失敗</string>
|
||||
<string name="add_friend_search_result">新增</string>
|
||||
|
||||
|
||||
<!-- error toast -->
|
||||
<string name="agree_add_friend_fail">同意好友申請失敗</string>
|
||||
<string name="disagree_add_friend_fail">拒絕好友申請失敗</string>
|
||||
<string name="agree_apply_join_team_fail">同意入群申請失敗</string>
|
||||
<string name="disagree_apply_join_team_fail">拒絕入群申請失敗</string>
|
||||
<string name="agree_invite_team_fail">同意入群邀請失敗</string>
|
||||
<string name="disagree_invite_team_fail">拒絕入群邀請失敗</string>
|
||||
<string name="remove_black_fail">黑名單移除失敗</string>
|
||||
<string name="verify_duplicate_fail">該驗證訊息已在其他端處理</string>
|
||||
|
||||
<!-- selector-->
|
||||
<string name="select">選擇好友</string>
|
||||
<!-- <string name="selector_sure">確定(%d)</string>-->
|
||||
<string name="selector_sure">下一步</string>
|
||||
<string name="invite_sure">邀請</string>
|
||||
<!-- <string name="selector_sure_without_num">確定</string>-->
|
||||
<string name="selector_sure_without_num">下一步</string>
|
||||
<string name="contact_selector_max_count">最多選擇%s個好友</string>
|
||||
<string name="contact_selector_over_count">超出人數限制</string>
|
||||
<string name="selector_friend_empty">暫無好友</string>
|
||||
<string name="selector_group_empty">暫無群組聊天</string>
|
||||
<string name="select_empty_tips">請選擇聯絡人</string>
|
||||
<string name="fun_selector_close">關閉</string>
|
||||
<string name="fun_contact_search">搜尋</string>
|
||||
|
||||
<!-- search -->
|
||||
<string name="global_search_hint">請輸入使用者名稱/群組聊天名稱關鍵字</string>
|
||||
<string name="global_search_title">搜尋</string>
|
||||
<string name="global_searchfriend_title">搜尋好友</string>
|
||||
|
||||
<string name="global_search_friend_title">好友</string>
|
||||
<string name="global_search_group_title">討論群組</string>
|
||||
<string name="global_search_team_title">群組</string>
|
||||
<string name="global_search_empty">該使用者不存在</string>
|
||||
|
||||
<!-- common-->
|
||||
<string name="cancel">取消</string>
|
||||
<string name="contact_network_error_tip">目前網路不可用,請檢查你當網路設定。 </string>
|
||||
|
||||
<string name="contact_hint">你們還沒聊喔~</string>
|
||||
|
||||
<string name="fun_contact_search_hint_text">搜索</string>
|
||||
<string name="fun_contact_searchresult_text">首頁</string>
|
||||
<string name="fun_contact_searchresult_addtext">添加</string>
|
||||
<string name="fun_contact_searchself_txt">無法新增自己的帳號為好友喔! </string>
|
||||
<string name="fun_contact_searchfriends_txt">你們已經是好友了喔! </string>
|
||||
<string name="fun_contact_addfriends_verifymsg">填入驗證資訊</string>
|
||||
<string name="fun_contact_verifymsg_tips">請輸入驗證資訊</string>
|
||||
<string name="fun_contact_addfriends_remarks">備註</string>
|
||||
<string name="fun_contact_remarks_tips">請輸入備註</string>
|
||||
<string name="fun_contact_addfriends_send">發送</string>
|
||||
<string name="fun_contact_createteam_tips">使用名稱進行搜尋</string>
|
||||
<string name="fun_creategroup_members">成員 %d</string>
|
||||
<string name="fun_creategroup_uploadhead">上傳頭像</string>
|
||||
<string name="fun_creategroup_autojoin_tips">使用者收到邀請後就會加入群組,關閉此設定後要求成員加入群組需手動接受邀請。 </string>
|
||||
<string name="fun_creategroup_autojoin">使用者自動加入</string>
|
||||
<string name="fun_creategroup_name">群組名稱</string>
|
||||
<string name="fun_creategroup_title">設定群組檔案</string>
|
||||
<string name="fun_creategroup_sure">建立</string>
|
||||
<string name="fun_contactselector_last">最近聯絡 %d</string>
|
||||
<string name="fun_contactselector_mylove">特別關注 %d</string>
|
||||
<string name="fun_contactselector_members">全部好友 %d</string>
|
||||
<string name="fun_contactselector_result">找結果</string>
|
||||
<string name="fun_contactselector_teamqr">行動碼</string>
|
||||
<string name="fun_contactselector_teamurl">邀請網址</string>
|
||||
<string name="fun_verifymsg">驗證資訊</string>
|
||||
<string name="fun_specialgz_txt">特別關注</string>
|
||||
<string name="fun_searchresult_txt">找結果</string>
|
||||
<string name="fun_addmembers_txt">新增</string>
|
||||
<string name="fun_addmemberstoast_txt">最少保留一位好友</string>
|
||||
<string name="nmhmylg_txt">你們還沒聊過喔~</string>
|
||||
<string name="voom_message_txt">[短影音訊息]</string>
|
||||
<string name="gerenminp_txt">[名片]</string>
|
||||
<string name="zhuanzhang_chat_txt">[轉帳]</string>
|
||||
<string name="hongbao_chat_txt">[紅包]</string>
|
||||
<string name="albums_chat_txt">[相簿]</string>
|
||||
<string name="helppay_chat_txt">[幫忙代付]</string>
|
||||
<string name="inviteGroup_chat_txt">[邀請進群]</string>
|
||||
<string name="custom_chat_txt">[自訂訊息]</string>
|
||||
<string name="removeblack_txt">解除屏蔽</string>
|
||||
<string name="teamdissmiss_txt">該群已被解散</string>
|
||||
<string name="teamjoined_txt">您已經在該群組中</string>
|
||||
<string name="know_txt">我知道了</string>
|
||||
<string name="nodate_txt">暫無數據</string>
|
||||
|
||||
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,21 @@
|
||||
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package com.netease.yunxin.kit.contactkit.ui;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
@Test
|
||||
public void addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
||||