From 80bc8db302b584d6bace0e1dc76d4453349bd2fe Mon Sep 17 00:00:00 2001 From: HuanChengFly <609486518@qq.com> Date: Mon, 31 Aug 2020 23:21:31 +0800 Subject: [PATCH] =?UTF-8?q?pref:=20=E4=BF=AE=E6=94=B9=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E3=80=81=E6=90=9C=E5=90=A7=E7=95=8C=E9=9D=A2=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../post/activities/NewSearchActivity.kt | 4 + .../post/adapters/SearchForumAdapter.java | 70 ---------- .../tieba/post/adapters/SearchForumAdapter.kt | 56 ++++++++ .../post/adapters/SearchHistoryAdapter.kt | 14 ++ ...eadAdapter.java => SearchThreadAdapter.kt} | 97 +++++++------- .../adapters/SingleLayoutDelegateAdapter.kt | 44 +++++++ .../tieba/post/adapters/base/BaseAdapter.kt | 112 ++++++++++++++++ .../adapters/base/BaseMultiTypeAdapter.kt | 41 ++++++ .../adapters/base/BaseSingleTypeAdapter.kt | 30 +++++ .../tieba/post/adapters/base/interfaces.kt | 2 + .../components/AutoLineFeedLayoutManager.java | 4 + .../post/fragments/SearchForumFragment.java | 122 ------------------ .../post/fragments/SearchForumFragment.kt | 110 ++++++++++++++++ .../tieba/post/interfaces/ISearchFragment.kt | 4 + .../widgets/theme/TintTextInputEditText.kt | 37 ++++++ .../drawable/bg_bottom_radius_8dp_ripple.xml | 4 + .../res/drawable/bg_radius_8dp_ripple.xml | 6 + app/src/main/res/drawable/bg_ripple.xml | 4 + .../res/drawable/bg_top_radius_8dp_ripple.xml | 7 + .../res/drawable/ic_round_chevron_right.xml | 9 ++ .../main/res/drawable/ic_round_graphic_eq.xml | 9 ++ .../main/res/drawable/ic_round_keyboard.xml | 9 ++ .../main/res/drawable/ic_round_polymer.xml | 9 ++ .../main/res/layout/activity_new_search.xml | 6 + app/src/main/res/layout/footer_no_more.xml | 6 + .../res/layout/item_search_history_chip.xml | 20 +++ app/src/main/res/layout/layout_no_data.xml | 5 + app/src/main/res/menu/menu_search_thread.xml | 4 + 28 files changed, 601 insertions(+), 244 deletions(-) create mode 100644 app/src/main/java/com/huanchengfly/tieba/post/activities/NewSearchActivity.kt delete mode 100644 app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchForumAdapter.java create mode 100644 app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchForumAdapter.kt create mode 100644 app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchHistoryAdapter.kt rename app/src/main/java/com/huanchengfly/tieba/post/adapters/{SearchThreadAdapter.java => SearchThreadAdapter.kt} (57%) create mode 100644 app/src/main/java/com/huanchengfly/tieba/post/adapters/SingleLayoutDelegateAdapter.kt create mode 100644 app/src/main/java/com/huanchengfly/tieba/post/adapters/base/BaseAdapter.kt create mode 100644 app/src/main/java/com/huanchengfly/tieba/post/adapters/base/BaseMultiTypeAdapter.kt create mode 100644 app/src/main/java/com/huanchengfly/tieba/post/adapters/base/BaseSingleTypeAdapter.kt create mode 100644 app/src/main/java/com/huanchengfly/tieba/post/adapters/base/interfaces.kt create mode 100644 app/src/main/java/com/huanchengfly/tieba/post/components/AutoLineFeedLayoutManager.java delete mode 100644 app/src/main/java/com/huanchengfly/tieba/post/fragments/SearchForumFragment.java create mode 100644 app/src/main/java/com/huanchengfly/tieba/post/fragments/SearchForumFragment.kt create mode 100644 app/src/main/java/com/huanchengfly/tieba/post/interfaces/ISearchFragment.kt create mode 100644 app/src/main/java/com/huanchengfly/tieba/post/widgets/theme/TintTextInputEditText.kt create mode 100644 app/src/main/res/drawable/bg_bottom_radius_8dp_ripple.xml create mode 100644 app/src/main/res/drawable/bg_radius_8dp_ripple.xml create mode 100644 app/src/main/res/drawable/bg_ripple.xml create mode 100644 app/src/main/res/drawable/bg_top_radius_8dp_ripple.xml create mode 100644 app/src/main/res/drawable/ic_round_chevron_right.xml create mode 100644 app/src/main/res/drawable/ic_round_graphic_eq.xml create mode 100644 app/src/main/res/drawable/ic_round_keyboard.xml create mode 100644 app/src/main/res/drawable/ic_round_polymer.xml create mode 100644 app/src/main/res/layout/activity_new_search.xml create mode 100644 app/src/main/res/layout/footer_no_more.xml create mode 100644 app/src/main/res/layout/item_search_history_chip.xml create mode 100644 app/src/main/res/layout/layout_no_data.xml create mode 100644 app/src/main/res/menu/menu_search_thread.xml diff --git a/app/src/main/java/com/huanchengfly/tieba/post/activities/NewSearchActivity.kt b/app/src/main/java/com/huanchengfly/tieba/post/activities/NewSearchActivity.kt new file mode 100644 index 00000000..42dace0e --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/activities/NewSearchActivity.kt @@ -0,0 +1,4 @@ +package com.huanchengfly.tieba.post.activities + +class NewSearchActivity { +} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchForumAdapter.java b/app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchForumAdapter.java deleted file mode 100644 index 38bff620..00000000 --- a/app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchForumAdapter.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.huanchengfly.tieba.post.adapters; - -import android.app.Activity; -import android.content.Context; - -import com.huanchengfly.tieba.post.api.models.SearchForumBean; -import com.huanchengfly.tieba.post.R; -import com.huanchengfly.tieba.post.utils.ImageUtil; -import com.huanchengfly.tieba.post.utils.NavigationHelper; -import com.othershe.baseadapter.ViewHolder; -import com.othershe.baseadapter.base.MultiBaseAdapter; - -import java.util.ArrayList; -import java.util.List; - -public class SearchForumAdapter extends MultiBaseAdapter { - public static final int TYPE_EXACT = 0; - public static final int TYPE_FUZZY = 1; - private NavigationHelper navigationHelper; - - public SearchForumAdapter(Context context) { - super(context, null, true); - navigationHelper = NavigationHelper.newInstance(context); - } - - public void setData(SearchForumBean.DataBean data) { - List forumInfoBeans = new ArrayList<>(); - if (data.getExactMatch() != null && data.getExactMatch().getForumNameShow() != null) { - forumInfoBeans.add(data.getExactMatch()); - } - forumInfoBeans.addAll(data.getFuzzyMatch()); - setNewData(forumInfoBeans); - } - - private boolean canLoadGlide() { - if (mContext instanceof Activity) { - return !((Activity) mContext).isDestroyed(); - } - return false; - } - - @Override - protected void convert(ViewHolder viewHolder, SearchForumBean.ForumInfoBean forumInfoBean, int position, int type) { - viewHolder.setText(R.id.item_search_forum_title, forumInfoBean.getForumNameShow() + "吧"); - viewHolder.setOnClickListener(R.id.item_search_forum, (view) -> { - navigationHelper.navigationByData(NavigationHelper.ACTION_FORUM, forumInfoBean.getForumName()); - }); - ImageUtil.load(viewHolder.getView(R.id.item_search_forum_avatar), ImageUtil.LOAD_TYPE_AVATAR, forumInfoBean.getAvatar()); - if (type == TYPE_EXACT) { - SearchForumBean.ExactForumInfoBean exactForumInfoBean = (SearchForumBean.ExactForumInfoBean) forumInfoBean; - viewHolder.setText(R.id.item_search_forum_subtitle, exactForumInfoBean.getSlogan()); - } - } - - @Override - protected int getItemLayoutId(int type) { - if (type == TYPE_EXACT) { - return R.layout.item_search_forum_exact; - } - return R.layout.item_search_forum; - } - - @Override - protected int getViewType(int i, SearchForumBean.ForumInfoBean forumInfoBean) { - if (forumInfoBean instanceof SearchForumBean.ExactForumInfoBean) { - return TYPE_EXACT; - } - return TYPE_FUZZY; - } -} diff --git a/app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchForumAdapter.kt b/app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchForumAdapter.kt new file mode 100644 index 00000000..c8991384 --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchForumAdapter.kt @@ -0,0 +1,56 @@ +package com.huanchengfly.tieba.post.adapters + +import android.content.Context +import android.view.View +import com.alibaba.android.vlayout.layout.LinearLayoutHelper +import com.huanchengfly.tieba.post.R +import com.huanchengfly.tieba.post.adapters.base.BaseMultiTypeDelegateAdapter +import com.huanchengfly.tieba.post.api.models.SearchForumBean +import com.huanchengfly.tieba.post.api.models.SearchForumBean.ExactForumInfoBean +import com.huanchengfly.tieba.post.components.MyViewHolder +import com.huanchengfly.tieba.post.utils.ImageUtil +import com.huanchengfly.tieba.post.utils.NavigationHelper +import java.util.* + +class SearchForumAdapter(context: Context?) : BaseMultiTypeDelegateAdapter(context!!, LinearLayoutHelper()) { + private val navigationHelper: NavigationHelper + fun setData(data: SearchForumBean.DataBean) { + val forumInfoBeans: MutableList = ArrayList() + if (data.exactMatch != null && data.exactMatch.forumNameShow != null) { + forumInfoBeans.add(data.exactMatch) + } + forumInfoBeans.addAll(data.fuzzyMatch!!) + setData(forumInfoBeans) + } + + protected override fun convert(viewHolder: MyViewHolder, forumInfoBean: SearchForumBean.ForumInfoBean, position: Int, type: Int) { + viewHolder.setText(R.id.item_search_forum_title, forumInfoBean.forumNameShow + "吧") + viewHolder.setOnClickListener(R.id.item_search_forum) { view: View? -> navigationHelper.navigationByData(NavigationHelper.ACTION_FORUM, forumInfoBean.forumName) } + ImageUtil.load(viewHolder.getView(R.id.item_search_forum_avatar), ImageUtil.LOAD_TYPE_AVATAR, forumInfoBean.avatar) + if (type == TYPE_EXACT) { + val exactForumInfoBean = forumInfoBean as ExactForumInfoBean + viewHolder.setText(R.id.item_search_forum_subtitle, exactForumInfoBean.slogan) + } + } + + override fun getItemLayoutId(type: Int): Int { + return if (type == TYPE_EXACT) { + R.layout.item_search_forum_exact + } else R.layout.item_search_forum + } + + protected override fun getViewType(i: Int, forumInfoBean: SearchForumBean.ForumInfoBean): Int { + return if (forumInfoBean is ExactForumInfoBean) { + TYPE_EXACT + } else TYPE_FUZZY + } + + companion object { + const val TYPE_EXACT = 0 + const val TYPE_FUZZY = 1 + } + + init { + navigationHelper = NavigationHelper.newInstance(context) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchHistoryAdapter.kt b/app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchHistoryAdapter.kt new file mode 100644 index 00000000..dce20fb3 --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchHistoryAdapter.kt @@ -0,0 +1,14 @@ +package com.huanchengfly.tieba.post.adapters + +import android.content.Context +import com.huanchengfly.tieba.post.adapters.base.BaseSingleTypeAdapter +import com.huanchengfly.tieba.post.components.MyViewHolder +import com.huanchengfly.tieba.post.models.database.SearchHistory + +class SearchHistoryAdapter(context: Context) : BaseSingleTypeAdapter(context) { + override fun getItemLayoutId(): Int { + return 0 + } + + protected override fun convert(viewHolder: MyViewHolder, searchHistory: SearchHistory, position: Int) {} +} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchThreadAdapter.java b/app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchThreadAdapter.kt similarity index 57% rename from app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchThreadAdapter.java rename to app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchThreadAdapter.kt index 3c020308..83b0db1d 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchThreadAdapter.java +++ b/app/src/main/java/com/huanchengfly/tieba/post/adapters/SearchThreadAdapter.kt @@ -1,35 +1,50 @@ -package com.huanchengfly.tieba.post.adapters; +package com.huanchengfly.tieba.post.adapters -import android.content.Context; -import android.text.format.DateUtils; -import android.view.View; +import android.text.format.DateUtils +import android.view.View +import com.huanchengfly.tieba.post.R +import com.huanchengfly.tieba.post.adapters.base.BaseSingleTypeAdapter +import com.huanchengfly.tieba.post.api.models.SearchThreadBean +import com.huanchengfly.tieba.post.components.MyViewHolder +import com.huanchengfly.tieba.post.fragments.SearchThreadFragment +import com.huanchengfly.tieba.post.utils.NavigationHelper +import java.util.* -import com.allen.library.SuperTextView; -import com.huanchengfly.tieba.post.api.SearchThreadFilter; -import com.huanchengfly.tieba.post.api.SearchThreadOrder; -import com.huanchengfly.tieba.post.api.models.SearchThreadBean; -import com.huanchengfly.tieba.post.R; -import com.huanchengfly.tieba.post.components.dialogs.SingleChooseDialog; -import com.huanchengfly.tieba.post.fragments.SearchThreadFragment; -import com.huanchengfly.tieba.post.utils.NavigationHelper; -import com.huanchengfly.tieba.post.utils.Util; -import com.othershe.baseadapter.ViewHolder; -import com.othershe.baseadapter.base.CommonBaseAdapter; +class SearchThreadAdapter(fragment: SearchThreadFragment) : BaseSingleTypeAdapter(fragment.requireContext()) { + private val navigationHelper: NavigationHelper + private val order = 0 + private val filter = 0 + protected override fun convert(viewHolder: MyViewHolder, threadInfoBean: SearchThreadBean.ThreadInfoBean, position: Int) { + viewHolder.setOnClickListener(R.id.item_search_thread) { view: View? -> + val map: MutableMap = HashMap() + map["tid"] = threadInfoBean.tid + map["pid"] = threadInfoBean.pid + navigationHelper.navigationByData(NavigationHelper.ACTION_THREAD, map) + } + viewHolder.setText(R.id.item_search_thread_title, threadInfoBean.title) + viewHolder.setText(R.id.item_search_thread_content, threadInfoBean.content) + viewHolder.setText(R.id.item_search_thread_user, threadInfoBean.user!!.userName) + if (threadInfoBean.forumName == null) { + viewHolder.setText( + R.id.item_search_thread_info, + DateUtils.getRelativeTimeSpanString(threadInfoBean.time!!.toLong() * 1000L) + ) + } else { + viewHolder.setText( + R.id.item_search_thread_info, + threadInfoBean.forumName + " " + DateUtils.getRelativeTimeSpanString(threadInfoBean.time!!.toLong() * 1000L) + ) + } + } -import java.util.HashMap; -import java.util.Map; + override fun getItemLayoutId(): Int { + return R.layout.item_search_thread + } -public class SearchThreadAdapter extends CommonBaseAdapter { - private NavigationHelper navigationHelper; - private int order; - private int filter; - - public SearchThreadAdapter(SearchThreadFragment fragment) { - super(fragment.getContext(), null, true); - order = 0; - filter = 0; - Context context = fragment.getContext(); - navigationHelper = NavigationHelper.newInstance(context); + init { + val context = fragment.requireContext() + navigationHelper = NavigationHelper.newInstance(context) + /* View headerView = Util.inflate(context, R.layout.layout_search_header); if (headerView != null) { SuperTextView orderTextView = headerView.findViewById(R.id.search_order); @@ -73,28 +88,6 @@ public class SearchThreadAdapter extends CommonBaseAdapter { - Map map = new HashMap<>(); - map.put("tid", threadInfoBean.getTid()); - map.put("pid", threadInfoBean.getPid()); - navigationHelper.navigationByData(NavigationHelper.ACTION_THREAD, map); - }); - viewHolder.setText(R.id.item_search_thread_title, threadInfoBean.getTitle()); - viewHolder.setText(R.id.item_search_thread_content, threadInfoBean.getContent()); - viewHolder.setText(R.id.item_search_thread_user, threadInfoBean.getUser().getUserName()); - if (threadInfoBean.getForumName() == null) { - viewHolder.setText(R.id.item_search_thread_info, String.valueOf(DateUtils.getRelativeTimeSpanString(Long.valueOf(threadInfoBean.getTime()) * 1000L))); - } else { - viewHolder.setText(R.id.item_search_thread_info, threadInfoBean.getForumName() + " " + DateUtils.getRelativeTimeSpanString(Long.valueOf(threadInfoBean.getTime()) * 1000L)); - } - } - - @Override - protected int getItemLayoutId() { - return R.layout.item_search_thread; - } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/adapters/SingleLayoutDelegateAdapter.kt b/app/src/main/java/com/huanchengfly/tieba/post/adapters/SingleLayoutDelegateAdapter.kt new file mode 100644 index 00000000..c078408f --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/adapters/SingleLayoutDelegateAdapter.kt @@ -0,0 +1,44 @@ +package com.huanchengfly.tieba.post.adapters.base + +import android.content.Context +import android.view.View +import android.view.ViewGroup +import androidx.annotation.LayoutRes +import com.alibaba.android.vlayout.DelegateAdapter +import com.alibaba.android.vlayout.LayoutHelper +import com.alibaba.android.vlayout.layout.SingleLayoutHelper +import com.huanchengfly.tieba.post.components.MyViewHolder + +abstract class BaseSingleLayoutAdapter( + val context: Context, + val itemView: View +) : DelegateAdapter.Adapter() { + constructor( + context: Context, + @LayoutRes + layoutResId: Int + ) : this( + context, + View.inflate(context, layoutResId, null) + ) + + constructor( + context: Context, + createViewFunction: () -> View + ) : this( + context, + createViewFunction() + ) + + final override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder = MyViewHolder(itemView) + + final override fun onBindViewHolder(holder: MyViewHolder, position: Int) { + convert(holder, itemView) + } + + final override fun getItemCount(): Int = 1 + + override fun onCreateLayoutHelper(): LayoutHelper = SingleLayoutHelper() + + abstract fun convert(holder: MyViewHolder, itemView: View) +} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/adapters/base/BaseAdapter.kt b/app/src/main/java/com/huanchengfly/tieba/post/adapters/base/BaseAdapter.kt new file mode 100644 index 00000000..691dbd24 --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/adapters/base/BaseAdapter.kt @@ -0,0 +1,112 @@ +package com.huanchengfly.tieba.post.adapters.base + +import android.content.Context +import com.alibaba.android.vlayout.DelegateAdapter +import com.alibaba.android.vlayout.LayoutHelper +import com.huanchengfly.tieba.post.components.MyViewHolder + +abstract class BaseDelegateAdapter( + val context: Context, + val layoutHelper: LayoutHelper, + items: List? = null +) : DelegateAdapter.Adapter() { + private var itemList: MutableList = (items ?: emptyList()).toMutableList() + + var onItemClickListener: OnItemClickListener? = null + private set + + var onItemLongClickListener: OnItemLongClickListener? = null + private set + + fun setOnItemClickListener(listener: OnItemClickListener?) { + onItemClickListener = listener + } + + fun setOnItemClickListener(listener: ((viewHolder: MyViewHolder, item: Item, position: Int) -> Unit)?) { + onItemClickListener = object : OnItemClickListener { + override fun onClick(viewHolder: MyViewHolder, item: Item, position: Int) { + if (listener != null) { + listener(viewHolder, item, position) + } + } + } + } + + fun setOnItemLongClickListener(listener: OnItemLongClickListener?) { + onItemLongClickListener = listener + } + + fun setOnItemLongClickListener(listener: ((viewHolder: MyViewHolder, item: Item, position: Int) -> Boolean)?) { + onItemLongClickListener = object : OnItemLongClickListener { + override fun onLongClick(viewHolder: MyViewHolder, item: Item, position: Int): Boolean { + if (listener != null) { + return listener(viewHolder, item, position) + } + return false + } + } + } + + override fun getItemCount(): Int = getCount() + + override fun onCreateLayoutHelper(): LayoutHelper = layoutHelper + + fun getItem(position: Int): Item = itemList[position] + + fun getItemList(): MutableList = itemList + + fun getCount() = itemList.size + + fun setData(items: List?) { + itemList.clear() + itemList.addAll(items ?: emptyList()) + notifyDataSetChanged() + } + + open fun remove(position: Int) { + if (position < itemList.size && position >= 0) { + itemList.removeAt(position) + notifyItemRemoved(position) + if (position != itemList.size) { + this.notifyItemRangeChanged(position, itemList.size - position) + } + } + } + + open fun insert(items: List, position: Int) { + if (position <= itemList.size && position >= 0) { + itemList.addAll(position, items) + notifyItemRangeInserted(position, items.size) + this.notifyItemRangeChanged(position, itemList.size - position) + } + } + + open fun insert(items: List) { + insert(items, itemList.size) + } + + open fun insert(data: Item, position: Int) { + if (position <= itemList.size && position >= 0) { + itemList.add(position, data) + notifyItemInserted(position) + this.notifyItemRangeChanged(position, itemList.size - position) + } + } + + open fun insert(data: Item) { + this.insert(data, itemList.size) + } + + open fun reset() { + itemList.clear() + notifyDataSetChanged() + } + + interface OnItemClickListener { + fun onClick(viewHolder: MyViewHolder, item: Item, position: Int) + } + + interface OnItemLongClickListener { + fun onLongClick(viewHolder: MyViewHolder, item: Item, position: Int): Boolean + } +} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/adapters/base/BaseMultiTypeAdapter.kt b/app/src/main/java/com/huanchengfly/tieba/post/adapters/base/BaseMultiTypeAdapter.kt new file mode 100644 index 00000000..9f21e974 --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/adapters/base/BaseMultiTypeAdapter.kt @@ -0,0 +1,41 @@ +package com.huanchengfly.tieba.post.adapters.base + +import android.content.Context +import android.view.View +import android.view.ViewGroup +import com.alibaba.android.vlayout.LayoutHelper +import com.huanchengfly.tieba.post.components.MyViewHolder + +abstract class BaseMultiTypeDelegateAdapter( + context: Context, + layoutHelper: LayoutHelper +) : BaseDelegateAdapter( + context, layoutHelper +) { + protected abstract fun getItemLayoutId( + itemType: Int + ): Int + + protected abstract fun getViewType( + position: Int, + item: Item + ): Int + + final override fun getItemViewType(position: Int): Int { + return getViewType(position, getItem(position)) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder = MyViewHolder(context, getItemLayoutId(viewType)) + + override fun onBindViewHolder(holder: MyViewHolder, position: Int) { + holder.setItemOnClickListener(View.OnClickListener { + onItemClickListener?.onClick(holder, getItem(position), position) + }) + holder.setItemOnLongClickListener(View.OnLongClickListener { + onItemLongClickListener?.onLongClick(holder, getItem(position), position) ?: false + }) + convert(holder, getItem(position), position, getItemViewType(position)) + } + + protected abstract fun convert(viewHolder: MyViewHolder, item: Item, position: Int, viewType: Int) +} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/adapters/base/BaseSingleTypeAdapter.kt b/app/src/main/java/com/huanchengfly/tieba/post/adapters/base/BaseSingleTypeAdapter.kt new file mode 100644 index 00000000..427052cc --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/adapters/base/BaseSingleTypeAdapter.kt @@ -0,0 +1,30 @@ +package com.huanchengfly.tieba.post.adapters.base + +import android.content.Context +import android.view.View +import android.view.ViewGroup +import com.alibaba.android.vlayout.LayoutHelper +import com.huanchengfly.tieba.post.components.MyViewHolder + +abstract class BaseSingleTypeDelegateAdapter( + context: Context, + layoutHelper: LayoutHelper +) : BaseDelegateAdapter( + context, layoutHelper +) { + protected abstract fun getItemLayoutId(): Int + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder = MyViewHolder(context, getItemLayoutId()) + + override fun onBindViewHolder(holder: MyViewHolder, position: Int) { + holder.setItemOnClickListener(View.OnClickListener { + onItemClickListener?.onClick(holder, getItem(position), position) + }) + holder.setItemOnLongClickListener(View.OnLongClickListener { + onItemLongClickListener?.onLongClick(holder, getItem(position), position) ?: false + }) + convert(holder, getItem(position), position) + } + + protected abstract fun convert(viewHolder: MyViewHolder, item: Item, position: Int) +} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/adapters/base/interfaces.kt b/app/src/main/java/com/huanchengfly/tieba/post/adapters/base/interfaces.kt new file mode 100644 index 00000000..9e464113 --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/adapters/base/interfaces.kt @@ -0,0 +1,2 @@ +package com.huanchengfly.tieba.post.adapters.base + diff --git a/app/src/main/java/com/huanchengfly/tieba/post/components/AutoLineFeedLayoutManager.java b/app/src/main/java/com/huanchengfly/tieba/post/components/AutoLineFeedLayoutManager.java new file mode 100644 index 00000000..f14c9f87 --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/components/AutoLineFeedLayoutManager.java @@ -0,0 +1,4 @@ +package com.huanchengfly.tieba.post.components; + +public class AutoLineFeedLayoutManager { +} diff --git a/app/src/main/java/com/huanchengfly/tieba/post/fragments/SearchForumFragment.java b/app/src/main/java/com/huanchengfly/tieba/post/fragments/SearchForumFragment.java deleted file mode 100644 index ef810e1a..00000000 --- a/app/src/main/java/com/huanchengfly/tieba/post/fragments/SearchForumFragment.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.huanchengfly.tieba.post.fragments; - - -import android.os.Bundle; -import android.view.View; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import com.huanchengfly.tieba.post.api.TiebaApi; -import com.huanchengfly.tieba.post.api.models.SearchForumBean; -import com.huanchengfly.tieba.post.R; -import com.huanchengfly.tieba.post.adapters.SearchForumAdapter; -import com.huanchengfly.tieba.post.components.MyLinearLayoutManager; -import com.huanchengfly.tieba.post.components.dividers.SearchDivider; -import com.huanchengfly.tieba.post.utils.ThemeUtil; - -import org.jetbrains.annotations.NotNull; - -import butterknife.BindView; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; - -public class SearchForumFragment extends BaseFragment { - public static final String TAG = "SearchForumFragment"; - - public static final String ARG_KEYWORD = "keyword"; - @BindView(R.id.fragment_search_refresh_layout) - SwipeRefreshLayout refreshLayout; - @BindView(R.id.fragment_search_recycler_view) - RecyclerView recyclerView; - private String keyword; - private SearchForumAdapter mAdapter; - - private SearchForumBean.DataBean mData; - - public SearchForumFragment() { - } - - public static SearchForumFragment newInstance(String keyword) { - SearchForumFragment forumFragment = new SearchForumFragment(); - Bundle bundle = new Bundle(); - bundle.putString(ARG_KEYWORD, keyword); - forumFragment.setArguments(bundle); - return forumFragment; - } - - public void setKeyword(String keyword, boolean refresh) { - this.keyword = keyword; - if (refresh) { - refresh(); - } else { - this.mData = null; - mAdapter.reset(); - } - } - - @Override - protected void onFragmentVisibleChange(boolean isVisible) { - if (mData == null && isVisible) { - refresh(); - } - } - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (getArguments() != null) { - keyword = getArguments().getString(ARG_KEYWORD); - } - } - - @Override - int getLayoutId() { - return R.layout.fragment_search; - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - recyclerView.setLayoutManager(new MyLinearLayoutManager(getAttachContext())); - recyclerView.addItemDecoration(new SearchDivider(getAttachContext())); - mAdapter = new SearchForumAdapter(getAttachContext()); - mAdapter.setLoadEndView(R.layout.layout_footer_loadend); - mAdapter.setLoadFailedView(R.layout.layout_footer_load_failed); - recyclerView.setAdapter(mAdapter); - refreshLayout.setOnRefreshListener(this::refresh); - ThemeUtil.setThemeForSwipeRefreshLayout(refreshLayout); - } - - private void setRefreshing(boolean refreshing) { - if (refreshLayout != null) refreshLayout.setRefreshing(refreshing); - } - - private void refresh() { - setRefreshing(true); - TiebaApi.getInstance().searchForum(keyword).enqueue(new Callback() { - @Override - public void onResponse(@NotNull Call call, @NotNull Response response) { - mData = response.body().getData(); - mAdapter.setData(mData); - setRefreshing(false); - mAdapter.loadEnd(); - } - - @Override - public void onFailure(@NotNull Call call, @NotNull Throwable t) { - setRefreshing(false); - Toast.makeText(getAttachContext(), t.getMessage(), Toast.LENGTH_SHORT).show(); - } - }); - } - - @Override - protected void onFragmentFirstVisible() { - refresh(); - } -} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/fragments/SearchForumFragment.kt b/app/src/main/java/com/huanchengfly/tieba/post/fragments/SearchForumFragment.kt new file mode 100644 index 00000000..70694dc0 --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/fragments/SearchForumFragment.kt @@ -0,0 +1,110 @@ +package com.huanchengfly.tieba.post.fragments + +import android.os.Bundle +import android.view.View +import android.widget.Toast +import androidx.recyclerview.widget.RecyclerView +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import butterknife.BindView +import com.alibaba.android.vlayout.VirtualLayoutManager +import com.huanchengfly.tieba.post.R +import com.huanchengfly.tieba.post.adapters.SearchForumAdapter +import com.huanchengfly.tieba.post.api.TiebaApi.getInstance +import com.huanchengfly.tieba.post.api.models.SearchForumBean +import com.huanchengfly.tieba.post.interfaces.ISearchFragment +import com.huanchengfly.tieba.post.utils.ThemeUtil +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response + +class SearchForumFragment : BaseFragment(), ISearchFragment { + @BindView(R.id.fragment_search_refresh_layout) + var refreshLayout: SwipeRefreshLayout? = null + + @BindView(R.id.fragment_search_recycler_view) + var recyclerView: RecyclerView? = null + private var keyword: String? = null + private var mAdapter: SearchForumAdapter? = null + private var mData: SearchForumBean.DataBean? = null + override fun setKeyword( + keyword: String?, + needRefresh: Boolean + ) { + this.keyword = keyword + if (mAdapter != null) { + if (needRefresh) { + refresh() + } else { + mData = null + mAdapter!!.reset() + } + } + } + + override fun onFragmentVisibleChange(isVisible: Boolean) { + if (mData == null && isVisible) { + refresh() + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + if (arguments != null) { + keyword = arguments!!.getString(ARG_KEYWORD) + } + } + + public override fun getLayoutId(): Int { + return R.layout.fragment_search + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + recyclerView!!.layoutManager = VirtualLayoutManager(attachContext) + mAdapter = SearchForumAdapter(attachContext) + recyclerView!!.adapter = mAdapter + refreshLayout!!.setOnRefreshListener { refresh() } + ThemeUtil.setThemeForSwipeRefreshLayout(refreshLayout) + } + + private fun setRefreshing(refreshing: Boolean) { + if (refreshLayout != null) refreshLayout!!.isRefreshing = refreshing + } + + private fun refresh() { + if (keyword == null) { + return + } + setRefreshing(true) + getInstance().searchForum(keyword!!).enqueue(object : Callback { + override fun onResponse(call: Call, response: Response) { + mData = response.body()!!.data + reloadAdapters() + setRefreshing(false) + } + + override fun onFailure(call: Call, t: Throwable) { + setRefreshing(false) + Toast.makeText(attachContext, t.message, Toast.LENGTH_SHORT).show() + } + }) + } + + private fun reloadAdapters() {} + override fun onFragmentFirstVisible() { + refresh() + } + + companion object { + const val TAG = "SearchForumFragment" + const val ARG_KEYWORD = "keyword" + @JvmOverloads + fun newInstance(keyword: String? = null): SearchForumFragment { + val forumFragment = SearchForumFragment() + val bundle = Bundle() + bundle.putString(ARG_KEYWORD, keyword) + forumFragment.arguments = bundle + return forumFragment + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/interfaces/ISearchFragment.kt b/app/src/main/java/com/huanchengfly/tieba/post/interfaces/ISearchFragment.kt new file mode 100644 index 00000000..ff03040a --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/interfaces/ISearchFragment.kt @@ -0,0 +1,4 @@ +package com.huanchengfly.tieba.post.interfaces + +interface ISearchFragment { +} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/widgets/theme/TintTextInputEditText.kt b/app/src/main/java/com/huanchengfly/tieba/post/widgets/theme/TintTextInputEditText.kt new file mode 100644 index 00000000..c6c6aafd --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/widgets/theme/TintTextInputEditText.kt @@ -0,0 +1,37 @@ +package com.huanchengfly.tieba.post.widgets.theme + +import android.content.Context +import android.util.AttributeSet +import androidx.appcompat.widget.AppCompatEditText +import com.huanchengfly.tieba.post.R +import com.huanchengfly.tieba.post.ui.theme.interfaces.Tintable +import com.huanchengfly.tieba.post.ui.theme.utils.ColorStateListUtils + +class TintEditText @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = R.attr.editTextStyle +) : AppCompatEditText(context, attrs, defStyleAttr), Tintable { + private var textColorResId: Int + private var textColorHintResId: Int + + init { + if (isInEditMode || attrs == null) { + textColorResId = 0 + textColorHintResId = 0 + } else { + val array = getContext().obtainStyledAttributes(attrs, R.styleable.TintEditText, defStyleAttr, 0) + textColorResId = array.getResourceId(R.styleable.TintEditText_textColor, 0) + textColorHintResId = array.getResourceId(R.styleable.TintEditText_android_textColorHint, 0) + array.recycle() + } + tint() + } + + override fun tint() { + if (textColorResId != 0) { + setTextColor(ColorStateListUtils.createColorStateList(context, textColorResId)) + } + if (textColorHintResId != 0) { + setHintTextColor(ColorStateListUtils.createColorStateList(context, textColorHintResId)) + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_bottom_radius_8dp_ripple.xml b/app/src/main/res/drawable/bg_bottom_radius_8dp_ripple.xml new file mode 100644 index 00000000..48968d92 --- /dev/null +++ b/app/src/main/res/drawable/bg_bottom_radius_8dp_ripple.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_radius_8dp_ripple.xml b/app/src/main/res/drawable/bg_radius_8dp_ripple.xml new file mode 100644 index 00000000..710bea4c --- /dev/null +++ b/app/src/main/res/drawable/bg_radius_8dp_ripple.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_ripple.xml b/app/src/main/res/drawable/bg_ripple.xml new file mode 100644 index 00000000..9287b65e --- /dev/null +++ b/app/src/main/res/drawable/bg_ripple.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_top_radius_8dp_ripple.xml b/app/src/main/res/drawable/bg_top_radius_8dp_ripple.xml new file mode 100644 index 00000000..3a5f7fee --- /dev/null +++ b/app/src/main/res/drawable/bg_top_radius_8dp_ripple.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_round_chevron_right.xml b/app/src/main/res/drawable/ic_round_chevron_right.xml new file mode 100644 index 00000000..29772976 --- /dev/null +++ b/app/src/main/res/drawable/ic_round_chevron_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_round_graphic_eq.xml b/app/src/main/res/drawable/ic_round_graphic_eq.xml new file mode 100644 index 00000000..3932127d --- /dev/null +++ b/app/src/main/res/drawable/ic_round_graphic_eq.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_round_keyboard.xml b/app/src/main/res/drawable/ic_round_keyboard.xml new file mode 100644 index 00000000..71116165 --- /dev/null +++ b/app/src/main/res/drawable/ic_round_keyboard.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_round_polymer.xml b/app/src/main/res/drawable/ic_round_polymer.xml new file mode 100644 index 00000000..2a9b5f95 --- /dev/null +++ b/app/src/main/res/drawable/ic_round_polymer.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_new_search.xml b/app/src/main/res/layout/activity_new_search.xml new file mode 100644 index 00000000..1766253b --- /dev/null +++ b/app/src/main/res/layout/activity_new_search.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/footer_no_more.xml b/app/src/main/res/layout/footer_no_more.xml new file mode 100644 index 00000000..61a4490a --- /dev/null +++ b/app/src/main/res/layout/footer_no_more.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_search_history_chip.xml b/app/src/main/res/layout/item_search_history_chip.xml new file mode 100644 index 00000000..d7451568 --- /dev/null +++ b/app/src/main/res/layout/item_search_history_chip.xml @@ -0,0 +1,20 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_no_data.xml b/app/src/main/res/layout/layout_no_data.xml new file mode 100644 index 00000000..8469a444 --- /dev/null +++ b/app/src/main/res/layout/layout_no_data.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_search_thread.xml b/app/src/main/res/menu/menu_search_thread.xml new file mode 100644 index 00000000..fe187c0c --- /dev/null +++ b/app/src/main/res/menu/menu_search_thread.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file