pref: 修改吧内搜索样式

This commit is contained in:
HuanChengFly 2020-10-05 21:02:14 +08:00
parent b72256daae
commit 38d14d89d4
5 changed files with 283 additions and 181 deletions

View File

@ -1,139 +1,131 @@
package com.huanchengfly.tieba.post.activities; package com.huanchengfly.tieba.post.activities
import android.content.Intent; import android.graphics.Color
import android.graphics.Color; import android.os.Bundle
import android.os.Bundle; import android.view.ViewGroup
import android.view.ViewGroup; import android.view.inputmethod.EditorInfo
import android.widget.EditText
import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import com.google.android.material.textfield.TextInputLayout
import com.huanchengfly.tieba.post.R
import com.huanchengfly.tieba.post.adapters.SearchPostAdapter
import com.huanchengfly.tieba.post.api.TiebaApi.getInstance
import com.huanchengfly.tieba.post.api.models.SearchPostBean
import com.huanchengfly.tieba.post.components.MyLinearLayoutManager
import com.huanchengfly.tieba.post.components.dividers.SpacesItemDecoration
import com.huanchengfly.tieba.post.dpToPx
import com.huanchengfly.tieba.post.utils.ThemeUtil
import com.huanchengfly.tieba.post.utils.Util
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import androidx.recyclerview.widget.LinearLayoutManager; class SearchPostActivity : BaseActivity() {
import androidx.recyclerview.widget.RecyclerView; @BindView(R.id.search_post_refresh_layout)
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; lateinit var refreshLayout: SmartRefreshLayout
import com.huanchengfly.tieba.post.api.TiebaApi; @BindView(R.id.search_post_recycler_view)
import com.huanchengfly.tieba.post.api.models.SearchPostBean; lateinit var recyclerView: RecyclerView
import com.huanchengfly.tieba.post.R;
import com.huanchengfly.tieba.post.adapters.SearchPostAdapter;
import com.huanchengfly.tieba.post.components.MyLinearLayoutManager;
import com.huanchengfly.tieba.post.components.dividers.RecycleViewDivider;
import com.huanchengfly.tieba.post.utils.ThemeUtil;
import com.huanchengfly.tieba.post.utils.Util;
import com.lapism.searchview.Search;
import com.lapism.searchview.widget.SearchView;
import org.jetbrains.annotations.NotNull; @BindView(R.id.search_bar)
lateinit var searchBar: TextInputLayout
import retrofit2.Call; @BindView(R.id.search_edit_text)
import retrofit2.Callback; lateinit var editText: EditText
import retrofit2.Response;
public class SearchPostActivity extends BaseActivity implements Search.OnQueryTextListener { lateinit var searchPostAdapter: SearchPostAdapter
public static final String TAG = SearchPostActivity.class.getSimpleName(); private var forumName: String? = null
public static final String PARAM_FORUM = "forum_name"; private var keyword: String? = null
public static final String PARAM_KEYWORD = "keyword"; set(value) {
private SwipeRefreshLayout refreshLayout; field = value
private RecyclerView recyclerView; if (value != null) refreshLayout.autoRefresh()
private SearchPostAdapter searchPostAdapter; }
private String forumName; private var page = 1
private String keyword;
private int page;
private SearchView searchView;
@Override override fun getLayoutId(): Int = R.layout.activity_search_post
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); override fun onCreate(savedInstanceState: Bundle?) {
setContentView(R.layout.activity_search_post); super.onCreate(savedInstanceState)
ThemeUtil.setTranslucentThemeBackground(findViewById(R.id.background)); ThemeUtil.setTranslucentThemeBackground(findViewById(R.id.background))
Util.setStatusBarTransparent(this); Util.setStatusBarTransparent(this)
getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
getWindow().getDecorView().setBackgroundColor(Color.TRANSPARENT); window.decorView.setBackgroundColor(Color.TRANSPARENT)
getWindow().setBackgroundDrawableResource(R.drawable.bg_trans); window.setBackgroundDrawableResource(R.drawable.bg_trans)
Intent intent = getIntent(); val intent = intent
forumName = intent.getStringExtra(PARAM_FORUM); forumName = intent.getStringExtra(PARAM_FORUM)
if (forumName == null) { if (forumName == null) {
finish(); finish()
} }
findView(); initView()
initView(); keyword = intent.getStringExtra(PARAM_KEYWORD)
keyword = intent.getStringExtra(PARAM_KEYWORD);
if (keyword != null) { if (keyword != null) {
searchView.setText(keyword); editText.setText(keyword)
refresh();
} }
} }
private void findView() { private fun initView() {
searchView = (SearchView) findViewById(R.id.toolbar_search_view); refreshLayout.apply {
refreshLayout = (SwipeRefreshLayout) findViewById(R.id.search_post_refresh_layout); ThemeUtil.setThemeForSmartRefreshLayout(this)
recyclerView = (RecyclerView) findViewById(R.id.search_post_recycler_view); setOnLoadMoreListener { loadMore() }
} setOnRefreshListener { refresh() }
private void initView() {
ThemeUtil.setThemeForSwipeRefreshLayout(refreshLayout);
searchPostAdapter = new SearchPostAdapter(this);
searchPostAdapter.setLoadingView(R.layout.layout_footer_loading);
searchPostAdapter.setLoadEndView(R.layout.layout_footer_loadend);
searchPostAdapter.setLoadFailedView(R.layout.layout_footer_load_failed);
searchPostAdapter.setOnLoadMoreListener(this::loadMore);
recyclerView.setLayoutManager(new MyLinearLayoutManager(this));
recyclerView.addItemDecoration(new RecycleViewDivider(this, LinearLayoutManager.VERTICAL, R.drawable.drawable_divider_8dp));
recyclerView.setAdapter(searchPostAdapter);
refreshLayout.setOnRefreshListener(this::refresh);
searchView.setHint(getString(R.string.hint_search_in_ba, forumName));
searchView.setOnQueryTextListener(this);
searchView.setOnLogoClickListener(this::finish);
}
public void refresh() {
refreshLayout.setRefreshing(true);
page = 1;
TiebaApi.getInstance().searchPost(keyword, forumName, false, page, 30).enqueue(new Callback<SearchPostBean>() {
@Override
public void onResponse(@NotNull Call<SearchPostBean> call, @NotNull Response<SearchPostBean> response) {
SearchPostBean data = response.body();
if (!"1".equals(data.getPage().getHasMore())) {
searchPostAdapter.loadEnd();
}
searchPostAdapter.setNewData(data.getPostList());
refreshLayout.setRefreshing(false);
}
@Override
public void onFailure(@NotNull Call<SearchPostBean> call, @NotNull Throwable t) {
searchPostAdapter.loadFailed();
refreshLayout.setRefreshing(false);
}
});
}
public void loadMore(boolean isReload) {
if (!isReload) {
page += 1;
} }
TiebaApi.getInstance().searchPost(keyword, forumName, false, page, 30).enqueue(new Callback<SearchPostBean>() { searchPostAdapter = SearchPostAdapter(this)
@Override searchPostAdapter.setOnItemClickListener { _, item, _ ->
public void onResponse(@NotNull Call<SearchPostBean> call, @NotNull Response<SearchPostBean> response) { ThreadActivity.launch(this, item.tid!!, item.pid)
SearchPostBean data = response.body(); }
if (!"1".equals(data.getPage().getHasMore())) { recyclerView.apply {
searchPostAdapter.loadEnd(); layoutManager = MyLinearLayoutManager(this@SearchPostActivity)
} addItemDecoration(SpacesItemDecoration(0, 0, 0, 8.dpToPx()))
searchPostAdapter.setLoadMoreData(data.getPostList()); adapter = searchPostAdapter
}
searchBar.setStartIconOnClickListener { finish() }
editText.setOnEditorActionListener { v, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
keyword = v.text.toString()
return@setOnEditorActionListener true
} }
return@setOnEditorActionListener false
@Override }
public void onFailure(@NotNull Call<SearchPostBean> call, @NotNull Throwable t) { editText.hint = getString(R.string.hint_search_in_ba, forumName)
searchPostAdapter.loadFailed();
}
});
} }
@Override fun refresh() {
public boolean onQueryTextSubmit(CharSequence query) { page = 1
keyword = query.toString(); getInstance().searchPost(keyword!!, forumName!!, false, page, 30).enqueue(object : Callback<SearchPostBean> {
refresh(); override fun onResponse(call: Call<SearchPostBean>, response: Response<SearchPostBean>) {
return true; val data = response.body()
searchPostAdapter.setData(data!!.postList)
refreshLayout.finishRefresh()
refreshLayout.setNoMoreData("1" != data.page!!.hasMore)
}
override fun onFailure(call: Call<SearchPostBean?>, t: Throwable) {
refreshLayout.finishRefresh(false)
}
})
} }
@Override private fun loadMore() {
public void onQueryTextChange(CharSequence newText) { getInstance().searchPost(keyword!!, forumName!!, false, page + 1, 30).enqueue(object : Callback<SearchPostBean> {
override fun onResponse(call: Call<SearchPostBean>, response: Response<SearchPostBean>) {
val data = response.body()
page += 1
data!!.postList?.let { searchPostAdapter.insert(it) }
refreshLayout.finishLoadMore()
refreshLayout.setNoMoreData("1" != data.page!!.hasMore)
}
override fun onFailure(call: Call<SearchPostBean?>, t: Throwable) {
refreshLayout.finishLoadMore(false)
}
})
}
companion object {
val TAG = SearchPostActivity::class.java.simpleName
const val PARAM_FORUM = "forum_name"
const val PARAM_KEYWORD = "keyword"
} }
} }

View File

@ -1,50 +1,63 @@
package com.huanchengfly.tieba.post.adapters; package com.huanchengfly.tieba.post.adapters
import android.content.Context; import android.content.Context
import android.widget.TextView; import android.graphics.Color
import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.core.text.HtmlCompat
import com.huanchengfly.tieba.post.R
import com.huanchengfly.tieba.post.adapters.base.BaseSingleTypeAdapter
import com.huanchengfly.tieba.post.api.models.SearchPostBean
import com.huanchengfly.tieba.post.components.MyViewHolder
import com.huanchengfly.tieba.post.ui.theme.utils.ThemeUtils
import com.huanchengfly.tieba.post.utils.TimeUtils.getRelativeTimeString
import androidx.core.text.HtmlCompat; class SearchPostAdapter(context: Context) : BaseSingleTypeAdapter<SearchPostBean.ThreadInfoBean>(context) {
override fun convert(viewHolder: MyViewHolder, item: SearchPostBean.ThreadInfoBean, position: Int) {
import com.huanchengfly.tieba.post.R; val contentTextView = viewHolder.getView<TextView>(R.id.item_search_thread_content)
import com.huanchengfly.tieba.post.api.models.SearchPostBean; val titleTextView = viewHolder.getView<TextView>(R.id.item_search_thread_title)
import com.huanchengfly.tieba.post.utils.NavigationHelper; titleTextView.text = HtmlCompat.fromHtml(item.title!!.getReplaced(), HtmlCompat.FROM_HTML_MODE_COMPACT)
import com.huanchengfly.tieba.post.utils.TimeUtils; contentTextView.text = HtmlCompat.fromHtml(item.content!!.getReplaced(), HtmlCompat.FROM_HTML_MODE_COMPACT)
import com.othershe.baseadapter.ViewHolder; viewHolder.setText(R.id.item_search_thread_user, item.author!!.nameShow)
import com.othershe.baseadapter.base.CommonBaseAdapter; if (item.forumName == null) {
viewHolder.setText(R.id.item_search_thread_info, getRelativeTimeString(context, item.time!!))
import java.util.HashMap;
import java.util.Map;
public class SearchPostAdapter extends CommonBaseAdapter<SearchPostBean.ThreadInfoBean> {
private NavigationHelper navigationHelper;
public SearchPostAdapter(Context context) {
super(context, null, true);
navigationHelper = NavigationHelper.newInstance(context);
}
@Override
protected void convert(ViewHolder viewHolder, SearchPostBean.ThreadInfoBean threadInfoBean, int position) {
viewHolder.setOnClickListener(R.id.item_search_thread, (view) -> {
Map<String, String> map = new HashMap<>();
map.put("tid", threadInfoBean.getTid());
map.put("pid", threadInfoBean.getPid());
navigationHelper.navigationByData(NavigationHelper.ACTION_THREAD, map);
});
TextView contentTextView = viewHolder.getView(R.id.item_search_thread_content);
TextView titleTextView = viewHolder.getView(R.id.item_search_thread_title);
titleTextView.setText(HtmlCompat.fromHtml(threadInfoBean.getTitle(), HtmlCompat.FROM_HTML_MODE_COMPACT));
contentTextView.setText(HtmlCompat.fromHtml(threadInfoBean.getContent(), HtmlCompat.FROM_HTML_MODE_COMPACT));
viewHolder.setText(R.id.user_name, threadInfoBean.getAuthor().getNameShow());
if (threadInfoBean.getForumName() == null) {
viewHolder.setText(R.id.user_content, TimeUtils.getRelativeTimeString(mContext, threadInfoBean.getTime()));
} else { } else {
viewHolder.setText(R.id.user_content, mContext.getString(R.string.template_two_string, threadInfoBean.getForumName(), TimeUtils.getRelativeTimeString(mContext, threadInfoBean.getTime()))); viewHolder.setText(R.id.item_search_thread_info, context.getString(R.string.template_two_string, item.forumName, getRelativeTimeString(context, item.time!!)))
} }
} }
@Override private fun String.getReplaced(): String {
protected int getItemLayoutId() { return replace("<em>", "<strong><font color=\"${toString(ThemeUtils.getColorById(context, R.color.default_color_accent))}\">").replace("</em>", "</font></strong>")
return R.layout.item_search_thread; }
override fun getItemLayoutId(): Int {
return R.layout.item_search_posts
}
companion object {
fun toString(red: Int, green: Int, blue: Int): String {
val hr = Integer.toHexString(red)
val hg = Integer.toHexString(green)
val hb = Integer.toHexString(blue)
return "#" + fixHexString(hr) + fixHexString(hg) + fixHexString(hb)
}
private fun fixHexString(hex: String): String {
var hexString = hex
if (hexString.isEmpty()) {
hexString = "00"
}
if (hexString.length == 1) {
hexString = "0$hexString"
}
if (hexString.length > 2) {
hexString = hexString.substring(0, 2)
}
return hexString
}
fun toString(@ColorInt color: Int): String {
return toString(Color.red(color), Color.green(color), Color.blue(color))
}
} }
} }

View File

@ -45,7 +45,6 @@ class SearchPostBean {
@SerializedName("fname") @SerializedName("fname")
val forumName: String? = null val forumName: String? = null
val author: AuthorBean? = null val author: AuthorBean? = null
} }
class AuthorBean { class AuthorBean {
@ -53,6 +52,5 @@ class SearchPostBean {
@SerializedName("name_show") @SerializedName("name_show")
val nameShow: String? = null val nameShow: String? = null
} }
} }

View File

@ -6,35 +6,76 @@
android:id="@+id/background" android:id="@+id/background"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/transparent" app:backgroundTint="@color/default_color_window_background"
tools:context=".activities.SearchPostActivity"> tools:context=".activities.SearchPostActivity">
<com.google.android.material.appbar.AppBarLayout <com.huanchengfly.tieba.post.widgets.theme.TintAppBarLayout
android:id="@+id/appbar" android:id="@+id/appbar"
android:background="@color/transparent"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:stateListAnimator="@animator/appbar_elevation"> android:stateListAnimator="@animator/appbar_elevation"
<com.lapism.searchview.widget.SearchView app:backgroundTint="@color/default_color_toolbar">
style="@style/Widget.SearchBar.Flat"
app:search_version_margins="toolbar"
app:search_version="toolbar"
app:search_hint="@string/hint_search"
android:id="@+id/toolbar_search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.appbar.AppBarLayout>
<com.huanchengfly.tieba.post.widgets.theme.TintSwipeRefreshLayout <com.huanchengfly.tieba.post.widgets.theme.TintTextInputLayout
android:id="@+id/search_bar"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:boxBackgroundColor="@color/color_toolbar_bar"
app:boxCollapsedPaddingTop="0dp"
app:boxCornerRadiusBottomEnd="8dp"
app:boxCornerRadiusBottomStart="8dp"
app:boxCornerRadiusTopEnd="8dp"
app:boxCornerRadiusTopStart="8dp"
app:boxStrokeWidth="0dp"
app:boxStrokeWidthFocused="0dp"
app:hintEnabled="false"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:hintTextColor="@color/default_color_primary"
app:placeholderTextColor="@color/default_color_primary"
app:startIconDrawable="@drawable/ic_round_arrow_back">
<com.huanchengfly.tieba.post.widgets.theme.TintTextInputEditText
android:imeOptions="actionSearch"
android:inputType="text"
android:id="@+id/search_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:hint="@string/hint_search"
android:textColorHint="@color/default_color_text_secondary" />
</com.huanchengfly.tieba.post.widgets.theme.TintTextInputLayout>
</com.huanchengfly.tieba.post.widgets.theme.TintAppBarLayout>
<com.scwang.smart.refresh.layout.SmartRefreshLayout
app:srlDragRate="0.8"
app:srlEnableOverScrollBounce="true"
app:srlEnableOverScrollDrag="true"
android:id="@+id/search_post_refresh_layout" android:id="@+id/search_post_refresh_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/transparent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"> app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/search_post_recycler_view" <com.huanchengfly.tieba.post.widgets.theme.TintMaterialHeader
android:background="@color/transparent" android:id="@+id/refresh_header"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
</com.huanchengfly.tieba.post.widgets.theme.TintSwipeRefreshLayout>
<androidx.recyclerview.widget.RecyclerView
android:paddingTop="@dimen/card_margin"
android:paddingStart="@dimen/card_margin"
android:paddingEnd="@dimen/card_margin"
android:clipToPadding="false"
android:id="@+id/search_post_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.huanchengfly.tieba.post.components.LoadMoreFooter
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
</com.huanchengfly.tieba.post.widgets.theme.TintCoordinatorLayout> </com.huanchengfly.tieba.post.widgets.theme.TintCoordinatorLayout>

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<com.huanchengfly.tieba.post.widgets.theme.TintRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:id="@+id/item_search_thread"
android:orientation="vertical"
android:background="@drawable/bg_radius_8dp_ripple"
app:backgroundTint="@color/default_color_card">
<com.huanchengfly.tieba.post.widgets.theme.TintTextView
android:id="@+id/item_search_thread_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tint="@color/default_color_text"
android:textSize="16sp"
android:layout_marginBottom="4dp"
android:maxLines="1"
android:ellipsize="end"
android:textStyle="bold"
tools:text="Title" />
<com.huanchengfly.tieba.post.widgets.theme.TintTextView
android:id="@+id/item_search_thread_content"
android:layout_below="@id/item_search_thread_title"
tools:text="Content"
android:textSize="14sp"
app:tint="@color/default_color_text"
android:layout_width="match_parent"
android:layout_marginBottom="4dp"
android:maxLines="3"
android:ellipsize="end"
android:layout_height="wrap_content" />
<com.huanchengfly.tieba.post.widgets.theme.TintTextView
android:id="@+id/item_search_thread_user"
android:layout_below="@id/item_search_thread_content"
tools:text="幻了个城fly"
android:textSize="12sp"
app:tint="@color/default_color_text_secondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<com.huanchengfly.tieba.post.widgets.theme.TintTextView
android:layout_alignWithParentIfMissing="true"
android:layout_toEndOf="@id/item_search_thread_user"
android:layout_alignParentEnd="true"
android:gravity="end"
android:id="@+id/item_search_thread_info"
android:layout_below="@id/item_search_thread_content"
tools:text="minecraft吧 · 刚刚"
android:textSize="12sp"
app:tint="@color/default_color_text_secondary"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.huanchengfly.tieba.post.widgets.theme.TintRelativeLayout>