From 427d10158b7b7e4b0cd467800a390ab8fb97eea0 Mon Sep 17 00:00:00 2001 From: zlzw <583819556@qq.com> Date: Fri, 13 Oct 2023 18:29:38 +0800 Subject: [PATCH] update --- OneToOne/build.gradle | 1 + OneToOne/src/main/AndroidManifest.xml | 1 + .../onetoone/activity/HomeSearchActivity.java | 20 + .../activity/HomepageRankingActivity.java | 24 +- .../activity/fragments/FriendsFragment.java | 7 +- .../fragments/home/HomeRankFragment.java | 143 +++++-- .../fragments/home/RecommendFragment.java | 5 +- .../message/ChatMessageFragment.java | 55 ++- .../onetoone/adapter/HomeRankListAdapter.java | 124 ++++++ .../com/shayu/onetoone/bean/HomeRankBean.java | 2 + .../shayu/onetoone/manager/OTONetManager.java | 21 + .../shayu/onetoone/manager/RouteManager.java | 7 + .../shayu/onetoone/network/OneToOneApi.java | 15 +- .../onetoone/utils/ConversationUtils.java | 3 + .../CustomizableRadioButton.java | 201 +++++++++ .../flexboxradiogroup/FlexBoxRadioGroup.java | 363 ++++++++++++++++ .../FlexBoxSingleCheckableGroup.java | 396 ++++++++++++++++++ .../main/res/drawable/bg_home_search_btn.xml | 5 + .../main/res/drawable/bg_home_search_text.xml | 5 + .../main/res/drawable/bg_search_input_2.xml | 5 + .../main/res/drawable/bg_search_select.xml | 9 + .../main/res/drawable/bg_search_unselect.xml | 9 + .../rc_ext_toggle_voice.png} | Bin .../src/main/res/layout/activity_search.xml | 261 ++++++++++++ .../main/res/layout/fragment_home_ranking.xml | 21 +- .../src/main/res/layout/item_home_rank.xml | 159 +++++++ .../res/layout/rc_extension_input_panel.xml | 4 +- OneToOne/src/main/res/layout/view_search.xml | 73 ++++ .../src/main/res/mipmap-xxhdpi/ic_search.png | Bin 0 -> 2040 bytes OneToOne/src/main/res/values/attrs.xml | 8 + OneToOne/src/main/res/values/style.xml | 3 + 31 files changed, 1887 insertions(+), 63 deletions(-) create mode 100644 OneToOne/src/main/java/com/shayu/onetoone/activity/HomeSearchActivity.java create mode 100644 OneToOne/src/main/java/com/shayu/onetoone/adapter/HomeRankListAdapter.java create mode 100644 OneToOne/src/main/java/com/shayu/onetoone/widget/flexboxradiogroup/CustomizableRadioButton.java create mode 100644 OneToOne/src/main/java/com/shayu/onetoone/widget/flexboxradiogroup/FlexBoxRadioGroup.java create mode 100644 OneToOne/src/main/java/com/shayu/onetoone/widget/flexboxradiogroup/FlexBoxSingleCheckableGroup.java create mode 100644 OneToOne/src/main/res/drawable/bg_home_search_btn.xml create mode 100644 OneToOne/src/main/res/drawable/bg_home_search_text.xml create mode 100644 OneToOne/src/main/res/drawable/bg_search_input_2.xml create mode 100644 OneToOne/src/main/res/drawable/bg_search_select.xml create mode 100644 OneToOne/src/main/res/drawable/bg_search_unselect.xml rename OneToOne/src/main/res/{mipmap-xxhdpi/ic_msg_audio.png => drawable/rc_ext_toggle_voice.png} (100%) create mode 100644 OneToOne/src/main/res/layout/activity_search.xml create mode 100644 OneToOne/src/main/res/layout/item_home_rank.xml create mode 100644 OneToOne/src/main/res/layout/view_search.xml create mode 100644 OneToOne/src/main/res/mipmap-xxhdpi/ic_search.png create mode 100644 OneToOne/src/main/res/values/attrs.xml diff --git a/OneToOne/build.gradle b/OneToOne/build.gradle index dc7b73b2e..a1c705d82 100644 --- a/OneToOne/build.gradle +++ b/OneToOne/build.gradle @@ -99,5 +99,6 @@ dependencies { implementation 'com.github.luqiming666:SwipeRecyclerView:1.4.8'//支持侧滑删除 implementation 'com.google.android.material:material:1.6.1' implementation 'com.blankj:utilcode:1.30.0'//獲取uuid + implementation 'com.google.android.flexbox:flexbox:3.0.0'//自动换行框架 } diff --git a/OneToOne/src/main/AndroidManifest.xml b/OneToOne/src/main/AndroidManifest.xml index b7bfb6f79..ea4b1a185 100644 --- a/OneToOne/src/main/AndroidManifest.xml +++ b/OneToOne/src/main/AndroidManifest.xml @@ -141,6 +141,7 @@ + fragments = new ArrayList<>(); @@ -43,6 +45,7 @@ public class HomepageRankingActivity extends AbsOTOActivity { dslTabLayout = findViewById(R.id.dslTabLayout); radioGroup = findViewById(R.id.radioGroup); + viewPagerChangeCallback = new ViewPagerChangeCallback(); ViewPager2Delegate.Companion.install(viewPager, dslTabLayout, false); fragments.add(new HomeRankFragment(HomeRankFragment.TYPE_CHARM));//魅力 @@ -71,10 +74,19 @@ public class HomepageRankingActivity extends AbsOTOActivity { }); mDay.setOnClickListener(v -> { setRadioColor(mDay, mWeek); + fragments.get(viewPager.getCurrentItem()).setDate(HomeRankFragment.DATE_DAY); }); mWeek.setOnClickListener(v -> { setRadioColor(mWeek, mDay); + fragments.get(viewPager.getCurrentItem()).setDate(HomeRankFragment.DATE_WEEK); }); + viewPager.registerOnPageChangeCallback(viewPagerChangeCallback); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + viewPager.unregisterOnPageChangeCallback(viewPagerChangeCallback); } private void setRadioColor(RadioButton select, RadioButton unSelect) { @@ -83,4 +95,12 @@ public class HomepageRankingActivity extends AbsOTOActivity { select.setBackgroundResource(R.drawable.bg_home_rank_day_select); unSelect.setBackgroundResource(R.drawable.bg_home_rank_day); } + + private class ViewPagerChangeCallback extends ViewPager2.OnPageChangeCallback { + @Override + public void onPageSelected(int position) { + super.onPageSelected(position); + fragments.get(position).setDate(mDay.isChecked()?HomeRankFragment.DATE_DAY:HomeRankFragment.DATE_WEEK); + } + } } diff --git a/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/FriendsFragment.java b/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/FriendsFragment.java index 0b274110f..19a4a89e6 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/FriendsFragment.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/FriendsFragment.java @@ -16,8 +16,7 @@ import com.angcyo.tablayout.delegate2.ViewPager2Delegate; import com.shayu.onetoone.R; import com.shayu.onetoone.activity.fragments.home.HotFragment; import com.shayu.onetoone.activity.fragments.home.RecommendFragment; -import com.shayu.onetoone.activity.fragments.message.MsgFriendFragment; -import com.shayu.onetoone.activity.fragments.message.MsgMessageFragment; +import com.shayu.onetoone.manager.RouteManager; import java.util.ArrayList; import java.util.List; @@ -47,6 +46,10 @@ public class FriendsFragment extends BaseFragment { return fragments.size(); } }); + findViewById(R.id.btn_top).setOnClickListener(v ->{ + RouteManager.forwardActivity(RouteManager.ACTIVITY_HOME_RANK); + + }); } @Override diff --git a/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/home/HomeRankFragment.java b/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/home/HomeRankFragment.java index 06e4258c1..2732087d6 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/home/HomeRankFragment.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/home/HomeRankFragment.java @@ -1,6 +1,5 @@ package com.shayu.onetoone.activity.fragments.home; -import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -9,56 +8,89 @@ import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.NonNull; + import com.google.android.material.appbar.AppBarLayout; import com.opensource.svgaplayer.SVGAImageView; import com.shayu.onetoone.R; import com.shayu.onetoone.activity.fragments.BaseFragment; -import com.shayu.onetoone.adapter.HomeRecommendListAdapter; +import com.shayu.onetoone.adapter.HomeRankListAdapter; import com.shayu.onetoone.bean.HomeRankBean; -import com.shayu.onetoone.bean.UserBean; import com.shayu.onetoone.listener.OnAppbarListener; +import com.shayu.onetoone.manager.OTONetManager; import com.yanzhenjie.recyclerview.SwipeRecyclerView; -import com.yunbao.common.bean.IMLoginModel; -import com.yunbao.common.custom.CommonRefreshView; -import com.yunbao.common.custom.MyRadioButton; +import com.yunbao.common.glide.ImgLoader; +import com.yunbao.common.http.base.HttpCallback; import com.yunbao.common.utils.ToastUtil; +import java.util.ArrayList; +import java.util.List; + +import io.rong.imkit.widget.refresh.SmartRefreshLayout; +import io.rong.imkit.widget.refresh.api.RefreshLayout; +import io.rong.imkit.widget.refresh.listener.OnLoadMoreListener; +import io.rong.imkit.widget.refresh.listener.OnRefreshListener; +import io.rong.imkit.widget.refresh.wrapper.RongRefreshHeader; import pl.droidsonroids.gif.GifImageView; public class HomeRankFragment extends BaseFragment { - public static final int TYPE_CHARM = 0; - public static final int TYPE_WEALTH = 1; + public static final int TYPE_CHARM = 1; + public static final int TYPE_WEALTH = 2; + public static final int DATE_DAY = 1; + public static final int DATE_WEEK = 2; private AppBarLayout rootView; private OnAppbarListener appbarListener; private SwipeRecyclerView mRecyclerView; - HomeRecommendListAdapter adapter; + HomeRankListAdapter adapter; + SmartRefreshLayout mRefreshLayout; + private HeadView hv; private int type; + private int date; public HomeRankFragment(int type) { super(); this.type = type; + this.date = DATE_DAY; } public void setAppbarListener(OnAppbarListener appbarListener) { this.appbarListener = appbarListener; } + public void setDate(int date) { + this.date = date; + updateData(); + } + @Override public void initView(View itemView) { rootView = findViewById(R.id.rootView); mRecyclerView = findViewById(R.id.recyclerView); - adapter = new HomeRecommendListAdapter(getContext()); + mRefreshLayout = findViewById(R.id.swipeRefreshLayout); + adapter = new HomeRankListAdapter(getContext()); + hv = new HeadView(rootView); mRecyclerView.setAdapter(adapter); - - rootView.addOnOffsetChangedListener(new AppBarLayout.BaseOnOffsetChangedListener() { + mRefreshLayout.setRefreshHeader(new RongRefreshHeader(this.getContext())); + mRefreshLayout.setRefreshFooter(new RongRefreshHeader(this.getContext())); + mRefreshLayout.setOnRefreshListener(new OnRefreshListener() { @Override - public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { - if (appbarListener != null) { - if (verticalOffset == 0) { - appbarListener.onShow(true); - } else if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()) { - appbarListener.onShow(false); - } + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + updateData(); + mRefreshLayout.finishRefresh(); + } + }); + mRefreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() { + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + refreshLayout.finishLoadMore(); + } + }); + rootView.addOnOffsetChangedListener((AppBarLayout.BaseOnOffsetChangedListener) (appBarLayout, verticalOffset) -> { + if (appbarListener != null) { + if (verticalOffset == 0) { + appbarListener.onShow(true); + } else if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()) { + appbarListener.onShow(false); } } }); @@ -68,8 +100,33 @@ public class HomeRankFragment extends BaseFragment { public View createView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_home_ranking, container, false); } - private void initData(){ + public void updateData() { + OTONetManager.getInstance(mContext) + .getHomeRank(type + "", date + "", new HttpCallback>() { + @Override + public void onSuccess(List tmp) { + List data = new ArrayList<>(); + for (int i = 0; i < 1; i++) { + data.addAll(tmp); + } + adapter.clear(); + hv.clear(); + for (int i = 0; i < data.size(); i++) { + if (i < 3) { + hv.setData(data.get(i), i); + continue; + } + adapter.add(data.get(i)); + } + adapter.notifyDataSetChanged(); + } + + @Override + public void onError(String error) { + + } + }); } class HeadView { @@ -117,33 +174,35 @@ public class HomeRankFragment extends BaseFragment { mVotes1 = itemView.findViewById(R.id.votes_1); mVotes2 = itemView.findViewById(R.id.votes_2); mVotes3 = itemView.findViewById(R.id.votes_3); - mSex1 = itemView.findViewById(R.id.sex_1); - mSex2 = itemView.findViewById(R.id.sex_2); - mSex3 = itemView.findViewById(R.id.sex_3); - diamond1 = itemView.findViewById(R.id.diamond1); - diamond2 = itemView.findViewById(R.id.diamond2); - diamond3 = itemView.findViewById(R.id.diamond3); - mBtnFollow1 = itemView.findViewById(R.id.btn_follow_1); - mBtnFollow2 = itemView.findViewById(R.id.btn_follow_2); - mBtnFollow3 = itemView.findViewById(R.id.btn_follow_3); + mSex1 = itemView.findViewById(R.id.sex_1); + mSex2 = itemView.findViewById(R.id.sex_2); + mSex3 = itemView.findViewById(R.id.sex_3); + diamond1 = itemView.findViewById(R.id.diamond1); + diamond2 = itemView.findViewById(R.id.diamond2); + diamond3 = itemView.findViewById(R.id.diamond3); + mBtnFollow1 = itemView.findViewById(R.id.btn_follow_1); + mBtnFollow2 = itemView.findViewById(R.id.btn_follow_2); + mBtnFollow3 = itemView.findViewById(R.id.btn_follow_3); svga1 = itemView.findViewById(R.id.svga1); svga2 = itemView.findViewById(R.id.svga2); svga3 = itemView.findViewById(R.id.svga3); } - void setData(HomeRankBean user, int position){ - getItem(position,mName1,mName2,mName3).setText(user.getUserNicename()); - getItem(position,mVotes1,mVotes2,mVotes3).setText(user.getMoney()); - if(user.isFollow()){ - getItem(position,mBtnFollow1,mBtnFollow2,mBtnFollow3).setVisibility(View.GONE); - }else{ - getItem(position,mBtnFollow1,mBtnFollow2,mBtnFollow3).setVisibility(View.VISIBLE); + + void setData(HomeRankBean user, int position) { + getItem(position,mItem1,mItem2,mItem3).setVisibility(View.VISIBLE); + getItem(position, mName1, mName2, mName3).setText(user.getUserNicename()); + getItem(position, mVotes1, mVotes2, mVotes3).setText(user.getMoney()); + if (user.isFollow()) { + getItem(position, mBtnFollow1, mBtnFollow2, mBtnFollow3).setVisibility(View.GONE); + } else { + getItem(position, mBtnFollow1, mBtnFollow2, mBtnFollow3).setVisibility(View.VISIBLE); } - if(user.getSex()==1) { + if (user.getSex() == 1) { getItem(position, mSex1, mSex2, mSex3).setImageResource(R.mipmap.ic_message_tab_man); - }else{ + } else { getItem(position, mSex1, mSex2, mSex3).setImageResource(R.mipmap.ic_message_tab_woman); } - switch (position){ + switch (position) { case 0: svga1.setImageResource(R.mipmap.ic_home_rank_top_1); break; @@ -154,8 +213,9 @@ public class HomeRankFragment extends BaseFragment { svga3.setImageResource(R.mipmap.ic_home_rank_top_3); break; } - + ImgLoader.display(mContext, user.getAvatar(), getItem(position, mAvatar1, mAvatar2, mAvatar3)); } + private T getItem(int position, T... views) { return views[position]; } @@ -170,5 +230,8 @@ public class HomeRankFragment extends BaseFragment { } } + public void clear() { + setVisibility(View.INVISIBLE,-1,mItem1,mItem2,mItem3); + } } } diff --git a/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/home/RecommendFragment.java b/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/home/RecommendFragment.java index c3406e1d1..9d3dbc0f0 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/home/RecommendFragment.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/home/RecommendFragment.java @@ -9,6 +9,7 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import com.shayu.onetoone.R; +import com.shayu.onetoone.activity.HomeSearchActivity; import com.shayu.onetoone.activity.fragments.BaseFragment; import com.shayu.onetoone.activity.HomepageRankingActivity; import com.shayu.onetoone.adapter.HomeRecommendListAdapter; @@ -52,8 +53,8 @@ public class RecommendFragment extends BaseFragment { } }); top.setOnClickListener(view -> { - // recyclerView.scrollToPosition(0); - startActivity(new Intent(getContext(), HomepageRankingActivity.class)); + // recyclerView.scrollToPosition(0); + startActivity(new Intent(getContext(), HomeSearchActivity.class)); }); initData(); } diff --git a/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/message/ChatMessageFragment.java b/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/message/ChatMessageFragment.java index 7735a5341..57b9201ff 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/message/ChatMessageFragment.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/activity/fragments/message/ChatMessageFragment.java @@ -5,6 +5,7 @@ import static android.content.Context.CLIPBOARD_SERVICE; import android.app.Dialog; import android.content.ClipData; import android.content.ClipboardManager; +import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.util.Log; @@ -53,10 +54,15 @@ import java.io.File; import java.lang.reflect.Field; import java.util.Arrays; import java.util.Date; +import java.util.List; import io.rong.imkit.IMCenter; import io.rong.imkit.conversation.MessageListAdapter; +import io.rong.imkit.conversation.extension.component.plugin.IPluginModule; +import io.rong.imkit.conversation.extension.component.plugin.ImagePlugin; import io.rong.imkit.model.UiMessage; +import io.rong.imkit.picture.PictureSelector; +import io.rong.imkit.picture.config.PictureMimeType; import io.rong.imlib.IRongCallback; import io.rong.imlib.RongIMClient; import io.rong.imlib.model.Conversation; @@ -98,7 +104,7 @@ public class ChatMessageFragment extends AbsConversationFragment { cameraUtil = new ProcessImageUtil(getActivity(), "com.shayu.onetoone.fileprovider"); mRongExtension.setVisibility(View.VISIBLE); - img.setOnClickListener(v -> cameraUtil.getImageByCamera()); + // img.setOnClickListener(v -> cameraUtil.getImageByCamera()); initCamera(); mSendBtn.setOnClickListener(v -> { @@ -231,6 +237,43 @@ public class ChatMessageFragment extends AbsConversationFragment { } }); }); + img.setOnClickListener(v -> { + new BottomListDialog(mContext) + .setStrings(Arrays.asList("相册", "拍照")) + .setSelect(new OnItemClickListener() { + @Override + public void onItemClick(String bean, int position) { + boolean isCamera = position == 1; + + SendMessageManager.sendMessageForText(targetId, "图片信息", new OnSendMessageListener() { + // PictureSelector.create(currentFragment) + // .openGallery(RongConfigCenter.conversationConfig().rc_media_selector_contain_video ? PictureMimeType.ofAll() : PictureMimeType.ofImage()) + // .loadImageEngine(RongConfigCenter.featureConfig().getKitImageEngine()) + // .setRequestedOrientation(1) + // .videoDurationLimit(RongIMClient.getInstance().getVideoLimitTime()) + // .maxSelectNum(9) + // .imageSpanCount(3) + // .isGif(true) + // .forResult(this.mRequestCode); + @Override + public void onSuccess(String token) { + super.onSuccess(token); + if (isCamera) { + PictureSelector.create(ChatMessageFragment.this).openCamera(PictureMimeType.ofImage()); + } else { + PictureSelector.create(ChatMessageFragment.this).openGallery(PictureMimeType.ofImage()); + } + + } + + @Override + public void onError(int status, String msg) { + super.onError(status, msg); + } + }); + } + }).showDialog(); + }); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); @@ -238,10 +281,6 @@ public class ChatMessageFragment extends AbsConversationFragment { } private void checkAuth(OnSendMessageListener listener) { - if (true) { - listener.onSuccess(""); - return; - } OTONetManager.getInstance(mContext) .getTargetUserInfo(Integer.parseInt(targetId), new HttpCallback() { @Override @@ -517,4 +556,10 @@ public class ChatMessageFragment extends AbsConversationFragment { protected MessageListAdapter onResolveAdapter() { return new MsgChatMessageListAdapter(this); } + + @Override + public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + ToastUtil.show("收到回调"); + } } diff --git a/OneToOne/src/main/java/com/shayu/onetoone/adapter/HomeRankListAdapter.java b/OneToOne/src/main/java/com/shayu/onetoone/adapter/HomeRankListAdapter.java new file mode 100644 index 000000000..53a444720 --- /dev/null +++ b/OneToOne/src/main/java/com/shayu/onetoone/adapter/HomeRankListAdapter.java @@ -0,0 +1,124 @@ +package com.shayu.onetoone.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.makeramen.roundedimageview.RoundedImageView; +import com.shayu.onetoone.R; +import com.shayu.onetoone.bean.FollowBean; +import com.shayu.onetoone.bean.HomeRankBean; +import com.shayu.onetoone.manager.OTONetManager; +import com.yunbao.common.glide.ImgLoader; +import com.yunbao.common.http.base.HttpCallback; +import com.yunbao.common.utils.ToastUtil; +import com.yunbao.common.utils.WordUtil; + +import java.util.ArrayList; +import java.util.List; + +public class HomeRankListAdapter extends RecyclerView.Adapter { + private Context mContext; + private List list; + + public HomeRankListAdapter(Context mContext) { + this.mContext = mContext; + list = new ArrayList<>(); + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new ViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_home_rank, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + holder.setData(list.get(position), position); + } + + @Override + public int getItemCount() { + return list.size(); + } + + public void setList(List data) { + this.list = data; + notifyDataSetChanged(); + } + + public void add(HomeRankBean homeRankBean) { + this.list.add(homeRankBean); + } + + public void clear() { + list.clear(); + notifyDataSetChanged(); + } + + public class ViewHolder extends RecyclerView.ViewHolder { + private TextView rank; + private RoundedImageView avatar; + private ImageView sex; + private TextView user_name; + private TextView level; + private ImageView ic_level; + private TextView money; + private Button follow; + + public ViewHolder(@NonNull View itemView) { + super(itemView); + rank = itemView.findViewById(R.id.rank); + avatar = itemView.findViewById(R.id.avatar); + sex = itemView.findViewById(R.id.sex); + user_name = itemView.findViewById(R.id.user_name); + level = itemView.findViewById(R.id.level); + ic_level = itemView.findViewById(R.id.ic_level); + money = itemView.findViewById(R.id.money); + follow = itemView.findViewById(R.id.follow); + } + + private void setData(HomeRankBean bean, int position) { + rank.setText(position + 4 + ""); + user_name.setText(bean.getUserNicename()); + level.setText("Lv." + bean.getLevel()); + money.setText(bean.getMoney()); + + if (bean.getSex() == 1) { + sex.setImageResource(R.mipmap.ic_message_tab_man); + } else { + sex.setImageResource(R.mipmap.ic_message_tab_woman); + } + if (bean.isFollow()) { + follow.setVisibility(View.GONE); + } else { + follow.setVisibility(View.VISIBLE); + } + ImgLoader.display(mContext, bean.getAvatar(), avatar); + follow.setText(bean.getUid()); + follow.setOnClickListener(v -> { + OTONetManager.getInstance(mContext) + .follow(v.getTag().toString(), new HttpCallback() { + @Override + public void onSuccess(FollowBean data) { + ToastUtil.show(WordUtil.getNewString(R.string.system_tip_success)); + v.setVisibility(View.GONE); + } + + @Override + public void onError(String error) { + + } + }); + }); + } + + } +} diff --git a/OneToOne/src/main/java/com/shayu/onetoone/bean/HomeRankBean.java b/OneToOne/src/main/java/com/shayu/onetoone/bean/HomeRankBean.java index 8c095c0a9..8a553606a 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/bean/HomeRankBean.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/bean/HomeRankBean.java @@ -1,5 +1,6 @@ package com.shayu.onetoone.bean; +import com.google.gson.annotations.SerializedName; import com.yunbao.common.bean.BaseModel; public class HomeRankBean extends BaseModel { @@ -16,6 +17,7 @@ public class HomeRankBean extends BaseModel { private int islive; private String avatar; private String avatarThumb; + @SerializedName("user_nicename") private String userNicename; private int sex; private int level; diff --git a/OneToOne/src/main/java/com/shayu/onetoone/manager/OTONetManager.java b/OneToOne/src/main/java/com/shayu/onetoone/manager/OTONetManager.java index 5553f53e0..e9b9d47e0 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/manager/OTONetManager.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/manager/OTONetManager.java @@ -10,6 +10,7 @@ import com.shayu.onetoone.bean.FollowBean; import com.shayu.onetoone.bean.GiftBean; import com.shayu.onetoone.bean.GreetBean; import com.shayu.onetoone.bean.HomeItemBean; +import com.shayu.onetoone.bean.HomeRankBean; import com.shayu.onetoone.bean.JoinAnchorBean; import com.shayu.onetoone.bean.MessageConsumeConfigBean; import com.shayu.onetoone.bean.OfficialNoticeBean; @@ -650,6 +651,26 @@ public class OTONetManager { } }).isDisposed(); } + public void getHomeRank(String type,String date, HttpCallback> callback) { + + API.get().otoApi(mContext) + .getHomeRank(type,date) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(model -> { + if (callback != null) { + callback.onSuccess(model.getData().getInfo()); + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + Log.e(TAG, "accept: ", throwable); + if (callback != null) { + callback.onError(mContext.getString(com.yunbao.common.R.string.net_error)); + } + } + }).isDisposed(); + } private MultipartBody.Part createUploadFile(File file) { RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file); diff --git a/OneToOne/src/main/java/com/shayu/onetoone/manager/RouteManager.java b/OneToOne/src/main/java/com/shayu/onetoone/manager/RouteManager.java index 75a0cfd9a..de76aa332 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/manager/RouteManager.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/manager/RouteManager.java @@ -14,6 +14,8 @@ public class RouteManager { public static final String ACTIVITY_ENTRY = "/activity/EntryActivity"; public static final String ACTIVITY_LOGIN = "/activity/LoginActivity"; public static final String ACTIVITY_WEB_VIEW = "/activity/WebViewActivity"; + public static final String ACTIVITY_HOME_RANK = "/activity/HomepageRankingActivity"; + public static final String ACTIVITY_HOME_SEARCH = "/activity/HomeSearchActivity"; public static void forwardMainActivity() { ARouter.getInstance().build(ACTIVITY_MAIN) @@ -46,5 +48,10 @@ public class RouteManager { .withString("url", url) .navigation(); } + public static void forwardActivity(String path) { + ARouter.getInstance().build(path) + .navigation(); + } + } diff --git a/OneToOne/src/main/java/com/shayu/onetoone/network/OneToOneApi.java b/OneToOne/src/main/java/com/shayu/onetoone/network/OneToOneApi.java index 77e1331cf..4b2e5be9f 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/network/OneToOneApi.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/network/OneToOneApi.java @@ -5,6 +5,7 @@ import com.shayu.onetoone.bean.FollowBean; import com.shayu.onetoone.bean.GiftBean; import com.shayu.onetoone.bean.GreetBean; import com.shayu.onetoone.bean.HomeItemBean; +import com.shayu.onetoone.bean.HomeRankBean; import com.shayu.onetoone.bean.JoinAnchorBean; import com.shayu.onetoone.bean.MessageConsumeConfigBean; import com.shayu.onetoone.bean.OfficialNoticeBean; @@ -121,7 +122,7 @@ public interface OneToOneApi { Observable>> getSystemMessageList(@Query("type") int type); @GET("/api/public/?service=Friendappmsg.sendAfter") - Observable>> sendMessage( + Observable> sendMessage( @Query("tuid") int tuid, @Query("type") int type, @Query("gift_id") String giftId, @@ -141,6 +142,18 @@ public interface OneToOneApi { @GET("/api/public/?service=User.setAttents") Observable>> follow(@Query("touid")String toUid); + /** + * + * @param type 1魅力榜 2财富榜 + * @param date 1日榜 2周榜 + */ + @GET("/api/public/?service=Friendapprank.list") + Observable>> getHomeRank( + @Query("type")String type, + @Query("date")String date + ); + + } diff --git a/OneToOne/src/main/java/com/shayu/onetoone/utils/ConversationUtils.java b/OneToOne/src/main/java/com/shayu/onetoone/utils/ConversationUtils.java index 463290a9d..34961499e 100644 --- a/OneToOne/src/main/java/com/shayu/onetoone/utils/ConversationUtils.java +++ b/OneToOne/src/main/java/com/shayu/onetoone/utils/ConversationUtils.java @@ -7,6 +7,9 @@ import io.rong.imkit.utils.RouteUtils; import io.rong.imlib.model.Conversation; import io.rong.imlib.model.ConversationIdentifier; +/** + * 跳转到会话页面 + */ public class ConversationUtils { public static void startConversation(Context mContext,String targetId){ ConversationIdentifier conversationIdentifier = new ConversationIdentifier(Conversation.ConversationType.PRIVATE, targetId); diff --git a/OneToOne/src/main/java/com/shayu/onetoone/widget/flexboxradiogroup/CustomizableRadioButton.java b/OneToOne/src/main/java/com/shayu/onetoone/widget/flexboxradiogroup/CustomizableRadioButton.java new file mode 100644 index 000000000..eb15136f4 --- /dev/null +++ b/OneToOne/src/main/java/com/shayu/onetoone/widget/flexboxradiogroup/CustomizableRadioButton.java @@ -0,0 +1,201 @@ +package com.shayu.onetoone.widget.flexboxradiogroup; + +import android.content.Context; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.AttributeSet; +import android.view.ViewDebug; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; +import android.widget.Checkable; +import android.widget.CompoundButton; +import android.widget.FrameLayout; + +public class CustomizableRadioButton extends FrameLayout implements Checkable { + private boolean mChecked = false; + private CompoundButton.OnCheckedChangeListener mOnCheckedChangeListener; + private CompoundButton compoundButton; + private boolean mBroadcasting; + + public CustomizableRadioButton(Context context) { + super(context); + init(); + } + + public CustomizableRadioButton(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + private void init() { + setClickable(true); + setFocusable(true); + + compoundButton = new CompoundButton(getContext()) { + @Override + public int getId() { + return CustomizableRadioButton.this.getId(); + } + }; + } + + /** + * {@inheritDoc} + *

+ * If the radio button is already checked, this method will not toggle the radio button. + */ + @Override + public void toggle() { + // we override to prevent toggle when the radio is already + // checked (as opposed to check boxes widgets) + if (!isChecked()) { + setChecked(!mChecked); + } + } + + @Override + public boolean performClick() { + /* + * XXX: These are tiny, need some surrounding 'expanded touch area', + * which will need to be implemented in Button if we only override + * performClick() + */ + + /* When clicked, toggle the state */ + toggle(); + return super.performClick(); + } + + @ViewDebug.ExportedProperty + public boolean isChecked() { + return mChecked; + } + + /** + *

Changes the checked state of this button.

+ * + * @param checked true to check the button, false to uncheck it + */ + public void setChecked(boolean checked) { + if (mChecked != checked) { + mChecked = checked; + refreshDrawableState(); + compoundButton.setChecked(checked); + + // Avoid infinite recursions if setChecked() is called from a listener + if (mBroadcasting) { + return; + } + + mBroadcasting = true; + if (mOnCheckedChangeListener != null) { + mOnCheckedChangeListener.onCheckedChanged(compoundButton, mChecked); + } + + + mBroadcasting = false; + } + } + + /** + * Register a callback to be invoked when the checked state of this button + * changes. + * + * @param listener the callback to call on checked state change + */ + public void setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener listener) { + mOnCheckedChangeListener = listener; + } + + + @Override + public void onInitializeAccessibilityEvent(AccessibilityEvent event) { + super.onInitializeAccessibilityEvent(event); + event.setClassName(CustomizableRadioButton.class.getName()); + event.setChecked(mChecked); + } + + @Override + public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(info); + info.setClassName(CustomizableRadioButton.class.getName()); + info.setCheckable(true); + info.setChecked(mChecked); + } + + private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked}; + + @Override + protected int[] onCreateDrawableState(int extraSpace) { + final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); + if (isChecked()) { + mergeDrawableStates(drawableState, CHECKED_STATE_SET); + } + return drawableState; + } + + + static class SavedState extends BaseSavedState { + boolean checked; + + /** + * Constructor called from {@link CompoundButton#onSaveInstanceState()} + */ + SavedState(Parcelable superState) { + super(superState); + } + + /** + * Constructor called from {@link #CREATOR} + */ + private SavedState(Parcel in) { + super(in); + checked = (Boolean) in.readValue(null); + } + + @Override + public void writeToParcel(Parcel out, int flags) { + super.writeToParcel(out, flags); + out.writeValue(checked); + } + + @Override + public String toString() { + return "CompoundButton.SavedState{" + + Integer.toHexString(System.identityHashCode(this)) + + " checked=" + checked + "}"; + } + + public static final Creator CREATOR + = new Creator() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } + + @Override + public Parcelable onSaveInstanceState() { + // Force our ancestor class to save its state + + Parcelable superState = super.onSaveInstanceState(); + + SavedState ss = new SavedState(superState); + + ss.checked = isChecked(); + return ss; + } + + @Override + public void onRestoreInstanceState(Parcelable state) { + SavedState ss = (SavedState) state; + + super.onRestoreInstanceState(ss.getSuperState()); + setChecked(ss.checked); + requestLayout(); + } +} \ No newline at end of file diff --git a/OneToOne/src/main/java/com/shayu/onetoone/widget/flexboxradiogroup/FlexBoxRadioGroup.java b/OneToOne/src/main/java/com/shayu/onetoone/widget/flexboxradiogroup/FlexBoxRadioGroup.java new file mode 100644 index 000000000..758e83b17 --- /dev/null +++ b/OneToOne/src/main/java/com/shayu/onetoone/widget/flexboxradiogroup/FlexBoxRadioGroup.java @@ -0,0 +1,363 @@ +package com.shayu.onetoone.widget.flexboxradiogroup; + +import android.content.Context; +import android.content.res.TypedArray; + +import android.util.AttributeSet; + +import android.view.View; +import android.view.ViewGroup; + +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; +import android.widget.CompoundButton; + +import android.widget.RadioButton; +import android.widget.RadioGroup; + +import com.google.android.flexbox.FlexDirection; +import com.google.android.flexbox.FlexboxLayout; +import com.shayu.onetoone.R; + +public class FlexBoxRadioGroup extends FlexboxLayout { + + + // holds the checked id; the selection is empty by default + private int mCheckedId = -1; + // tracks children radio buttons checked state + private CompoundButton.OnCheckedChangeListener mChildOnCheckedChangeListener; + // when true, mOnCheckedChangeListener discards events + private boolean mProtectFromCheckedChange = false; + private OnCheckedChangeListener mOnCheckedChangeListener; + private PassThroughHierarchyChangeListener mPassThroughListener; + + /** + * {@inheritDoc} + */ + public FlexBoxRadioGroup(Context context) { + super(context); + setFlexDirection(FlexDirection.ROW); + init(); + } + + /** + * {@inheritDoc} + */ + public FlexBoxRadioGroup(Context context, AttributeSet attrs) { + super(context, attrs); + + // retrieve selected radio button as requested by the user in the + // XML layout file + TypedArray attributes = context.obtainStyledAttributes( + attrs, R.styleable.FlexBoxRadioGroup); + + int value = attributes.getResourceId(R.styleable.FlexBoxRadioGroup_uiCheckedButton, View.NO_ID); + if (value != View.NO_ID) { + mCheckedId = value; + } + + attributes.recycle(); + init(); + } + + private void init() { + mChildOnCheckedChangeListener = new CheckedStateTracker(); + mPassThroughListener = new PassThroughHierarchyChangeListener(); + super.setOnHierarchyChangeListener(mPassThroughListener); + } + + /** + * {@inheritDoc} + */ + @Override + public void setOnHierarchyChangeListener(OnHierarchyChangeListener listener) { + // the user listener is delegated to our pass-through listener + mPassThroughListener.mOnHierarchyChangeListener = listener; + } + + /** + * {@inheritDoc} + */ + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + + // checks the appropriate radio button as requested in the XML file + if (mCheckedId != -1) { + mProtectFromCheckedChange = true; + setCheckedStateForView(mCheckedId, true); + mProtectFromCheckedChange = false; + setCheckedId(mCheckedId); + } + } + + @Override + public void addView(View child, int index, ViewGroup.LayoutParams params) { + if (child instanceof RadioButton) { + final RadioButton button = (RadioButton) child; + if (button.isChecked()) { + mProtectFromCheckedChange = true; + if (mCheckedId != -1) { + setCheckedStateForView(mCheckedId, false); + } + mProtectFromCheckedChange = false; + setCheckedId(button.getId()); + } + } + + super.addView(child, index, params); + } + + /** + *

Sets the selection to the radio button whose identifier is passed in + * parameter. Using -1 as the selection identifier clears the selection; + * such an operation is equivalent to invoking {@link #clearCheck()}.

+ * + * @param id the unique id of the radio button to select in this group + * @see #getCheckedRadioButtonId() + * @see #clearCheck() + */ + public void check(int id) { + // don't even bother + if (id != -1 && (id == mCheckedId)) { + return; + } + + if (mCheckedId != -1) { + setCheckedStateForView(mCheckedId, false); + } + + if (id != -1) { + setCheckedStateForView(id, true); + } + + setCheckedId(id); + } + + private void setCheckedId(int id) { + mCheckedId = id; + if (mOnCheckedChangeListener != null) { + mOnCheckedChangeListener.onCheckedChanged(this, mCheckedId); + } + } + + private void setCheckedStateForView(int viewId, boolean checked) { + View checkedView = findViewById(viewId); + if (checkedView != null && checkedView instanceof RadioButton) { + ((RadioButton) checkedView).setChecked(checked); + } + } + + /** + *

Returns the identifier of the selected radio button in this group. + * Upon empty selection, the returned value is -1.

+ * + * @return the unique id of the selected radio button in this group + * @attr ref android.R.styleable#RadioGroup_checkedButton + * @see #check(int) + * @see #clearCheck() + */ + public int getCheckedRadioButtonId() { + return mCheckedId; + } + + /** + *

Clears the selection. When the selection is cleared, no radio button + * in this group is selected and {@link #getCheckedRadioButtonId()} returns + * null.

+ * + * @see #check(int) + * @see #getCheckedRadioButtonId() + */ + public void clearCheck() { + check(-1); + } + + /** + *

Register a callback to be invoked when the checked radio button + * changes in this group.

+ * + * @param listener the callback to call on checked state change + */ + public void setOnCheckedChangeListener(OnCheckedChangeListener listener) { + mOnCheckedChangeListener = listener; + } + + /** + * {@inheritDoc} + */ +// @Override +// public FlexBoxRadioGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { +// return new FlexBoxRadioGroup.LayoutParams(getContext(), attrs); +// } + + /** + * {@inheritDoc} + */ + @Override + protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { + return p instanceof RadioGroup.LayoutParams; + } + + @Override + protected FlexboxLayout.LayoutParams generateDefaultLayoutParams() { + return new LayoutParams(RadioGroup.LayoutParams.WRAP_CONTENT, RadioGroup.LayoutParams.WRAP_CONTENT); + } + + @Override + public void onInitializeAccessibilityEvent(AccessibilityEvent event) { + super.onInitializeAccessibilityEvent(event); + event.setClassName(RadioGroup.class.getName()); + } + + @Override + public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(info); + info.setClassName(RadioGroup.class.getName()); + } + + /** + *

This set of layout parameters defaults the width and the height of + * the children to {@link #WRAP_CONTENT} when they are not specified in the + * XML file. Otherwise, this class uses the value read from the XML file.

+ */ + public static class LayoutParams extends FlexboxLayout.LayoutParams { + /** + * {@inheritDoc} + */ + public LayoutParams(Context c, AttributeSet attrs) { + super(c, attrs); + } + + /** + * {@inheritDoc} + */ + public LayoutParams(int w, int h) { + super(w, h); + } + +// /** +// * {@inheritDoc} +// */ +// public LayoutParams(int w, int h, float initWeight) { +// super(w, h, initWeight); +// } + + /** + * {@inheritDoc} + */ + public LayoutParams(ViewGroup.LayoutParams p) { + super(p); + } + + /** + * {@inheritDoc} + */ + public LayoutParams(MarginLayoutParams source) { + super(source); + } + + /** + *

Fixes the child's width to + * {@link ViewGroup.LayoutParams#WRAP_CONTENT} and the child's + * height to {@link ViewGroup.LayoutParams#WRAP_CONTENT} + * when not specified in the XML file.

+ * + * @param a the styled attributes set + * @param widthAttr the width attribute to fetch + * @param heightAttr the height attribute to fetch + */ + @Override + protected void setBaseAttributes(TypedArray a, + int widthAttr, int heightAttr) { + + if (a.hasValue(widthAttr)) { + width = a.getLayoutDimension(widthAttr, "layout_width"); + } else { + width = WRAP_CONTENT; + } + + if (a.hasValue(heightAttr)) { + height = a.getLayoutDimension(heightAttr, "layout_height"); + } else { + height = WRAP_CONTENT; + } + } + } + + /** + *

Interface definition for a callback to be invoked when the checked + * radio button changed in this group.

+ */ + public interface OnCheckedChangeListener { + /** + *

Called when the checked radio button has changed. When the + * selection is cleared, checkedId is -1.

+ * + * @param group the group in which the checked radio button has changed + * @param checkedId the unique identifier of the newly checked radio button + */ + void onCheckedChanged(FlexBoxRadioGroup group, int checkedId); + } + + private class CheckedStateTracker implements CompoundButton.OnCheckedChangeListener { + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + // prevents from infinite recursion + if (mProtectFromCheckedChange) { + return; + } + + mProtectFromCheckedChange = true; + if (mCheckedId != -1) { + setCheckedStateForView(mCheckedId, false); + } + mProtectFromCheckedChange = false; + + int id = buttonView.getId(); + setCheckedId(id); + } + } + + /** + *

A pass-through listener acts upon the events and dispatches them + * to another listener. This allows the table layout to set its own internal + * hierarchy change listener without preventing the user to setup his.

+ */ + private class PassThroughHierarchyChangeListener implements + OnHierarchyChangeListener { + private OnHierarchyChangeListener mOnHierarchyChangeListener; + + /** + * {@inheritDoc} + */ + public void onChildViewAdded(View parent, View child) { + if (parent == FlexBoxRadioGroup.this && child instanceof RadioButton) { + int id = child.getId(); + // generates an id if it's missing + if (id == View.NO_ID) { + id = child.hashCode(); + child.setId(id); + } + ((RadioButton) child).setOnCheckedChangeListener( + mChildOnCheckedChangeListener); + } + + if (mOnHierarchyChangeListener != null) { + mOnHierarchyChangeListener.onChildViewAdded(parent, child); + } + } + + /** + * {@inheritDoc} + */ + public void onChildViewRemoved(View parent, View child) { + if (parent == FlexBoxRadioGroup.this && child instanceof RadioButton) { + ((RadioButton) child).setOnCheckedChangeListener(null); + } + + if (mOnHierarchyChangeListener != null) { + mOnHierarchyChangeListener.onChildViewRemoved(parent, child); + } + } + } +} \ No newline at end of file diff --git a/OneToOne/src/main/java/com/shayu/onetoone/widget/flexboxradiogroup/FlexBoxSingleCheckableGroup.java b/OneToOne/src/main/java/com/shayu/onetoone/widget/flexboxradiogroup/FlexBoxSingleCheckableGroup.java new file mode 100644 index 000000000..f67ac0b11 --- /dev/null +++ b/OneToOne/src/main/java/com/shayu/onetoone/widget/flexboxradiogroup/FlexBoxSingleCheckableGroup.java @@ -0,0 +1,396 @@ +package com.shayu.onetoone.widget.flexboxradiogroup; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; +import android.widget.Checkable; +import android.widget.CompoundButton; + +import android.widget.RadioButton; +import android.widget.RadioGroup; + +import com.google.android.flexbox.FlexDirection; +import com.google.android.flexbox.FlexboxLayout; +import com.shayu.onetoone.R; + +import java.lang.reflect.Method; + + +public class FlexBoxSingleCheckableGroup extends FlexboxLayout { + + private static final String TAG = "FlexBoxSingleCheckableG"; + // holds the checked id; the selection is empty by default + private int mCheckedId = -1; + // tracks children radio buttons checked state + private CompoundButton.OnCheckedChangeListener mChildOnCheckedChangeListener; + // when true, mOnCheckedChangeListener discards events + private boolean mProtectFromCheckedChange = false; + private OnCheckedChangeListener mOnCheckedChangeListener; + private PassThroughHierarchyChangeListener mPassThroughListener; + + /** + * {@inheritDoc} + */ + public FlexBoxSingleCheckableGroup(Context context) { + super(context); + setFlexDirection(FlexDirection.ROW); + init(); + } + + /** + * {@inheritDoc} + */ + public FlexBoxSingleCheckableGroup(Context context, AttributeSet attrs) { + super(context, attrs); + + // retrieve selected radio button as requested by the user in the + // XML layout file + TypedArray attributes = context.obtainStyledAttributes( + attrs, R.styleable.FlexBoxRadioGroup); + + int value = attributes.getResourceId(R.styleable.FlexBoxRadioGroup_uiCheckedButton, View.NO_ID); + if (value != View.NO_ID) { + mCheckedId = value; + } + + attributes.recycle(); + init(); + } + + private void init() { + mChildOnCheckedChangeListener = new CheckedStateTracker(); + mPassThroughListener = new PassThroughHierarchyChangeListener(); + super.setOnHierarchyChangeListener(mPassThroughListener); + } + + /** + * {@inheritDoc} + */ + @Override + public void setOnHierarchyChangeListener(OnHierarchyChangeListener listener) { + // the user listener is delegated to our pass-through listener + mPassThroughListener.mOnHierarchyChangeListener = listener; + } + + /** + * {@inheritDoc} + */ + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + + // checks the appropriate radio button as requested in the XML file + if (mCheckedId != -1) { + mProtectFromCheckedChange = true; + setCheckedStateForView(mCheckedId, true); + mProtectFromCheckedChange = false; + setCheckedId(mCheckedId); + } + } + + + public void addView(View child, int index, ViewGroup.LayoutParams params, boolean isChecked) { + if (child instanceof Checkable) { + + if (isChecked) { + mProtectFromCheckedChange = true; + if (mCheckedId != -1) { + setCheckedStateForView(mCheckedId, false); + } + mProtectFromCheckedChange = false; + setCheckedId(child.getId()); + } + } + + super.addView(child, index, params); +// if (child instanceof RadioButton) { +// final RadioButton button = (RadioButton) child; +// if (button.isChecked()) { +// mProtectFromCheckedChange = true; +// if (mCheckedId != -1) { +// setCheckedStateForView(mCheckedId, false); +// } +// mProtectFromCheckedChange = false; +// setCheckedId(button.getId()); +// } +// } +// +// super.addView(child, index, params); + } + + /** + *

Sets the selection to the radio button whose identifier is passed in + * parameter. Using -1 as the selection identifier clears the selection; + * such an operation is equivalent to invoking {@link #clearCheck()}.

+ * + * @param id the unique id of the radio button to select in this group + * @see #getCheckedRadioButtonId() + * @see #clearCheck() + */ + public void check(int id) { + // don't even bother + if (id != -1 && (id == mCheckedId)) { + return; + } + + if (mCheckedId != -1) { + setCheckedStateForView(mCheckedId, false); + } + + if (id != -1) { + setCheckedStateForView(id, true); + } + + setCheckedId(id); + } + + private void setCheckedId(int id) { + mCheckedId = id; + if (mOnCheckedChangeListener != null) { + mOnCheckedChangeListener.onCheckedChanged(this, mCheckedId); + } + } + + private void setCheckedStateForView(int viewId, boolean checked) { + View checkedView = findViewById(viewId); + if (checkedView != null && checkedView instanceof Checkable) { + try { + Method m = checkedView.getClass() + .getMethod("setChecked", boolean.class); + m.invoke(checkedView, checked); + } catch (Exception e) { + Log.e(TAG, ""); + } + } + } + + /** + *

Returns the identifier of the selected radio button in this group. + * Upon empty selection, the returned value is -1.

+ * + * @return the unique id of the selected radio button in this group + * @attr ref android.R.styleable#RadioGroup_checkedButton + * @see #check(int) + * @see #clearCheck() + */ + public int getCheckedRadioButtonId() { + return mCheckedId; + } + + /** + *

Clears the selection. When the selection is cleared, no radio button + * in this group is selected and {@link #getCheckedRadioButtonId()} returns + * null.

+ * + * @see #check(int) + * @see #getCheckedRadioButtonId() + */ + public void clearCheck() { + check(-1); + } + + /** + *

Register a callback to be invoked when the checked radio button + * changes in this group.

+ * + * @param listener the callback to call on checked state change + */ + public void setOnCheckedChangeListener(OnCheckedChangeListener listener) { + mOnCheckedChangeListener = listener; + } + + /** + * {@inheritDoc} + */ +// @Override +// public FlexBoxRadioGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { +// return new FlexBoxRadioGroup.LayoutParams(getContext(), attrs); +// } + + /** + * {@inheritDoc} + */ + @Override + protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { + return p instanceof RadioGroup.LayoutParams; + } + + @Override + protected FlexboxLayout.LayoutParams generateDefaultLayoutParams() { + return new LayoutParams(RadioGroup.LayoutParams.WRAP_CONTENT, RadioGroup.LayoutParams.WRAP_CONTENT); + } + + @Override + public void onInitializeAccessibilityEvent(AccessibilityEvent event) { + super.onInitializeAccessibilityEvent(event); + event.setClassName(RadioGroup.class.getName()); + } + + @Override + public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(info); + info.setClassName(RadioGroup.class.getName()); + } + + /** + *

This set of layout parameters defaults the width and the height of + * the children to {@link #WRAP_CONTENT} when they are not specified in the + * XML file. Otherwise, this class uses the value read from the XML file.

+ */ + public static class LayoutParams extends FlexboxLayout.LayoutParams { + /** + * {@inheritDoc} + */ + public LayoutParams(Context c, AttributeSet attrs) { + super(c, attrs); + } + + /** + * {@inheritDoc} + */ + public LayoutParams(int w, int h) { + super(w, h); + } + +// /** +// * {@inheritDoc} +// */ +// public LayoutParams(int w, int h, float initWeight) { +// super(w, h, initWeight); +// } + + /** + * {@inheritDoc} + */ + public LayoutParams(ViewGroup.LayoutParams p) { + super(p); + } + + /** + * {@inheritDoc} + */ + public LayoutParams(MarginLayoutParams source) { + super(source); + } + + /** + *

Fixes the child's width to + * {@link ViewGroup.LayoutParams#WRAP_CONTENT} and the child's + * height to {@link ViewGroup.LayoutParams#WRAP_CONTENT} + * when not specified in the XML file.

+ * + * @param a the styled attributes set + * @param widthAttr the width attribute to fetch + * @param heightAttr the height attribute to fetch + */ + @Override + protected void setBaseAttributes(TypedArray a, + int widthAttr, int heightAttr) { + + if (a.hasValue(widthAttr)) { + width = a.getLayoutDimension(widthAttr, "layout_width"); + } else { + width = WRAP_CONTENT; + } + + if (a.hasValue(heightAttr)) { + height = a.getLayoutDimension(heightAttr, "layout_height"); + } else { + height = WRAP_CONTENT; + } + } + } + + /** + *

Interface definition for a callback to be invoked when the checked + * radio button changed in this group.

+ */ + public interface OnCheckedChangeListener { + /** + *

Called when the checked radio button has changed. When the + * selection is cleared, checkedId is -1.

+ * + * @param group the group in which the checked radio button has changed + * @param checkedId the unique identifier of the newly checked radio button + */ + void onCheckedChanged(FlexBoxSingleCheckableGroup group, int checkedId); + } + + private class CheckedStateTracker implements CompoundButton.OnCheckedChangeListener { + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + // prevents from infinite recursion + if (mProtectFromCheckedChange) { + return; + } + + mProtectFromCheckedChange = true; + if (mCheckedId != -1) { + setCheckedStateForView(mCheckedId, false); + } + mProtectFromCheckedChange = false; + + int id = buttonView.getId(); + setCheckedId(id); + } + } + + /** + *

A pass-through listener acts upon the events and dispatches them + * to another listener. This allows the table layout to set its own internal + * hierarchy change listener without preventing the user to setup his.

+ */ + private class PassThroughHierarchyChangeListener implements + OnHierarchyChangeListener { + private OnHierarchyChangeListener mOnHierarchyChangeListener; + + /** + * {@inheritDoc} + */ + public void onChildViewAdded(View parent, View child) { + if (parent == FlexBoxSingleCheckableGroup.this && child instanceof Checkable) { + int id = child.getId(); + // generates an id if it's missing + if (id == View.NO_ID) { + id = child.hashCode(); + child.setId(id); + } + try { + Method m = child.getClass() + .getMethod("setOnCheckedChangeListener", CompoundButton.OnCheckedChangeListener.class); + m.invoke(child, mChildOnCheckedChangeListener); + } catch (Exception e) { + Log.e(TAG, ""); + } + } + + if (mOnHierarchyChangeListener != null) { + mOnHierarchyChangeListener.onChildViewAdded(parent, child); + } + } + + /** + * {@inheritDoc} + */ + public void onChildViewRemoved(View parent, View child) { + if (parent == FlexBoxSingleCheckableGroup.this && child instanceof Checkable) { + ((RadioButton) child).setOnCheckedChangeListener(null); + try { + Method m = child.getClass() + .getMethod("setOnCheckedChangeListener", CompoundButton.OnCheckedChangeListener.class); + m.invoke(child, (Object[]) null); + } catch (Exception e) { + Log.e(TAG, ""); + } + } + + if (mOnHierarchyChangeListener != null) { + mOnHierarchyChangeListener.onChildViewRemoved(parent, child); + } + } + } +} \ No newline at end of file diff --git a/OneToOne/src/main/res/drawable/bg_home_search_btn.xml b/OneToOne/src/main/res/drawable/bg_home_search_btn.xml new file mode 100644 index 000000000..09a9ef524 --- /dev/null +++ b/OneToOne/src/main/res/drawable/bg_home_search_btn.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/OneToOne/src/main/res/drawable/bg_home_search_text.xml b/OneToOne/src/main/res/drawable/bg_home_search_text.xml new file mode 100644 index 000000000..9650a8433 --- /dev/null +++ b/OneToOne/src/main/res/drawable/bg_home_search_text.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/OneToOne/src/main/res/drawable/bg_search_input_2.xml b/OneToOne/src/main/res/drawable/bg_search_input_2.xml new file mode 100644 index 000000000..dcbd299eb --- /dev/null +++ b/OneToOne/src/main/res/drawable/bg_search_input_2.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/OneToOne/src/main/res/drawable/bg_search_select.xml b/OneToOne/src/main/res/drawable/bg_search_select.xml new file mode 100644 index 000000000..e3204fded --- /dev/null +++ b/OneToOne/src/main/res/drawable/bg_search_select.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/OneToOne/src/main/res/drawable/bg_search_unselect.xml b/OneToOne/src/main/res/drawable/bg_search_unselect.xml new file mode 100644 index 000000000..280ed07e9 --- /dev/null +++ b/OneToOne/src/main/res/drawable/bg_search_unselect.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/OneToOne/src/main/res/mipmap-xxhdpi/ic_msg_audio.png b/OneToOne/src/main/res/drawable/rc_ext_toggle_voice.png similarity index 100% rename from OneToOne/src/main/res/mipmap-xxhdpi/ic_msg_audio.png rename to OneToOne/src/main/res/drawable/rc_ext_toggle_voice.png diff --git a/OneToOne/src/main/res/layout/activity_search.xml b/OneToOne/src/main/res/layout/activity_search.xml new file mode 100644 index 000000000..fdfc1e036 --- /dev/null +++ b/OneToOne/src/main/res/layout/activity_search.xml @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OneToOne/src/main/res/layout/fragment_home_ranking.xml b/OneToOne/src/main/res/layout/fragment_home_ranking.xml index 8cf82f81b..88b17ae1b 100644 --- a/OneToOne/src/main/res/layout/fragment_home_ranking.xml +++ b/OneToOne/src/main/res/layout/fragment_home_ranking.xml @@ -56,8 +56,10 @@ @@ -69,9 +71,8 @@ android:layout_width="80dp" android:layout_height="80dp" android:layout_centerInParent="true" - android:layout_centerHorizontal="true" - android:layout_centerVertical="true" - android:layout_marginTop="10dp" /> + android:layout_marginTop="10dp" + android:src="@mipmap/ic_home_rank_top_1" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +