From 17763b21cdddc73cd3001074c22a6ee7993ade0c Mon Sep 17 00:00:00 2001 From: FongMi Date: Fri, 2 Sep 2022 15:16:11 +0800 Subject: [PATCH] Support search history --- .../tv/ui/activity/SearchActivity.java | 31 +++--- .../android/tv/ui/adapter/HistoryAdapter.java | 99 +++++++++++++++++++ .../android/tv/ui/adapter/WordAdapter.java | 67 +++++++++++++ .../tv/ui/presenter/WordPresenter.java | 48 --------- .../leanback/res/layout/activity_search.xml | 2 + app/src/leanback/res/layout/adapter_word.xml | 3 + .../fongmi/android/tv/player/ParseTask.java | 5 +- .../com/fongmi/android/tv/utils/Prefers.java | 8 ++ 8 files changed, 201 insertions(+), 62 deletions(-) create mode 100644 app/src/leanback/java/com/fongmi/android/tv/ui/adapter/HistoryAdapter.java create mode 100644 app/src/leanback/java/com/fongmi/android/tv/ui/adapter/WordAdapter.java delete mode 100644 app/src/leanback/java/com/fongmi/android/tv/ui/presenter/WordPresenter.java diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SearchActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SearchActivity.java index cccfc8c21..0a8b5c2e5 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SearchActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SearchActivity.java @@ -18,8 +18,6 @@ import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; -import androidx.leanback.widget.ArrayObjectAdapter; -import androidx.leanback.widget.ItemBridgeAdapter; import androidx.viewbinding.ViewBinding; import com.fongmi.android.tv.R; @@ -28,28 +26,28 @@ import com.fongmi.android.tv.bean.Suggest; import com.fongmi.android.tv.databinding.ActivitySearchBinding; import com.fongmi.android.tv.net.Callback; import com.fongmi.android.tv.net.OKHttp; +import com.fongmi.android.tv.ui.adapter.HistoryAdapter; +import com.fongmi.android.tv.ui.adapter.WordAdapter; import com.fongmi.android.tv.ui.custom.CustomKeyboard; import com.fongmi.android.tv.ui.custom.CustomListener; import com.fongmi.android.tv.ui.custom.SpaceItemDecoration; -import com.fongmi.android.tv.ui.presenter.WordPresenter; import com.fongmi.android.tv.utils.ResUtil; import com.fongmi.android.tv.utils.Utils; import java.io.IOException; -import java.util.Arrays; import java.util.List; import okhttp3.Call; import okhttp3.Response; -public class SearchActivity extends BaseActivity implements WordPresenter.OnClickListener, CustomKeyboard.Callback { +public class SearchActivity extends BaseActivity implements WordAdapter.OnClickListener, HistoryAdapter.OnClickListener, CustomKeyboard.Callback { private final ActivityResultLauncher launcherString = registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> onVoice()); private ActivitySearchBinding mBinding; - private ArrayObjectAdapter mHistoryAdapter; - private ArrayObjectAdapter mWordAdapter; private SpeechRecognizer mRecognizer; + private HistoryAdapter mHistoryAdapter; + private WordAdapter mWordAdapter; private Animation mFlicker; private Handler mHandler; @@ -98,12 +96,11 @@ public class SearchActivity extends BaseActivity implements WordPresenter.OnClic private void setRecyclerView() { mBinding.word.setHasFixedSize(true); - mBinding.history.setHasFixedSize(true); mBinding.word.addItemDecoration(new SpaceItemDecoration(1, 16)); + mBinding.word.setAdapter(mWordAdapter = new WordAdapter(this)); + mBinding.history.setHasFixedSize(true); mBinding.history.addItemDecoration(new SpaceItemDecoration(1, 16)); - mBinding.word.setAdapter(new ItemBridgeAdapter(mWordAdapter = new ArrayObjectAdapter(new WordPresenter(this)))); - mBinding.history.setAdapter(new ItemBridgeAdapter(mHistoryAdapter = new ArrayObjectAdapter(new WordPresenter(this)))); - mHistoryAdapter.setItems(Arrays.asList("測試1測試1", "測試2測試2", "測試3"), null); + mBinding.history.setAdapter(mHistoryAdapter = new HistoryAdapter(this)); } private void getHot() { @@ -112,7 +109,7 @@ public class SearchActivity extends BaseActivity implements WordPresenter.OnClic @Override public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException { List items = Hot.get(response.body().string()); - mHandler.post(() -> mWordAdapter.setItems(items, null)); + mHandler.post(() -> mWordAdapter.addAll(items)); } }); } @@ -123,7 +120,7 @@ public class SearchActivity extends BaseActivity implements WordPresenter.OnClic @Override public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException { List items = Suggest.get(response.body().string()); - mHandler.post(() -> mWordAdapter.setItems(items, null)); + mHandler.post(() -> mWordAdapter.addAll(items)); } }); } @@ -134,6 +131,13 @@ public class SearchActivity extends BaseActivity implements WordPresenter.OnClic onSearch(); } + @Override + public void onDataChanged(int size) { + int visible = size == 0 ? View.GONE : View.VISIBLE; + if (mBinding.historyLayout.getVisibility() == visible) return; + mBinding.historyLayout.setVisibility(visible); + } + @Override public void onSearch() { String keyword = mBinding.keyword.getText().toString().trim(); @@ -141,6 +145,7 @@ public class SearchActivity extends BaseActivity implements WordPresenter.OnClic Utils.hideKeyboard(mBinding.keyword); if (TextUtils.isEmpty(keyword)) return; CollectActivity.start(this, keyword); + mHandler.postDelayed(() -> mHistoryAdapter.add(keyword), 250); } @Override diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/adapter/HistoryAdapter.java b/app/src/leanback/java/com/fongmi/android/tv/ui/adapter/HistoryAdapter.java new file mode 100644 index 000000000..9627a6d51 --- /dev/null +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/adapter/HistoryAdapter.java @@ -0,0 +1,99 @@ +package com.fongmi.android.tv.ui.adapter; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.fongmi.android.tv.databinding.AdapterWordBinding; +import com.fongmi.android.tv.utils.Prefers; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import java.util.ArrayList; +import java.util.List; + +public class HistoryAdapter extends RecyclerView.Adapter { + + private final OnClickListener mListener; + private final List mItems; + private final Gson mGson; + + public HistoryAdapter(OnClickListener listener) { + this.mListener = listener; + this.mGson = new Gson(); + this.mItems = getItems(); + this.mListener.onDataChanged(mItems.size()); + } + + public interface OnClickListener { + + void onItemClick(String item); + + void onDataChanged(int size); + } + + public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { + + private final AdapterWordBinding binding; + + public ViewHolder(@NonNull AdapterWordBinding binding) { + super(binding.getRoot()); + this.binding = binding; + itemView.setOnClickListener(this); + itemView.setOnLongClickListener(this); + } + + @Override + public void onClick(View view) { + mListener.onItemClick(mItems.get(getLayoutPosition())); + } + + @Override + public boolean onLongClick(View v) { + mItems.remove(getLayoutPosition()); + notifyItemRemoved(getLayoutPosition()); + Prefers.putKeyword(mGson.toJson(mItems)); + mListener.onDataChanged(getItemCount()); + return true; + } + } + + private List getItems() { + if (Prefers.getKeyword().isEmpty()) return new ArrayList<>(); + return mGson.fromJson(Prefers.getKeyword(), new TypeToken>() {}.getType()); + } + + private void check(String item) { + int index = mItems.indexOf(item); + if (index == -1) return; + mItems.remove(index); + notifyItemRemoved(index); + } + + public void add(String item) { + check(item); + mItems.add(0, item); + notifyItemInserted(0); + Prefers.putKeyword(mGson.toJson(mItems)); + mListener.onDataChanged(getItemCount()); + } + + @Override + public int getItemCount() { + return mItems.size(); + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new ViewHolder(AdapterWordBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + holder.binding.text.setText(mItems.get(position)); + } +} diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/adapter/WordAdapter.java b/app/src/leanback/java/com/fongmi/android/tv/ui/adapter/WordAdapter.java new file mode 100644 index 000000000..e4fb97d68 --- /dev/null +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/adapter/WordAdapter.java @@ -0,0 +1,67 @@ +package com.fongmi.android.tv.ui.adapter; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.fongmi.android.tv.databinding.AdapterWordBinding; + +import java.util.ArrayList; +import java.util.List; + +public class WordAdapter extends RecyclerView.Adapter { + + private final OnClickListener mListener; + private final List mItems; + + public WordAdapter(OnClickListener listener) { + this.mItems = new ArrayList<>(); + this.mListener = listener; + } + + public interface OnClickListener { + + void onItemClick(String item); + } + + public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + + private final AdapterWordBinding binding; + + public ViewHolder(@NonNull AdapterWordBinding binding) { + super(binding.getRoot()); + this.binding = binding; + itemView.setOnClickListener(this); + } + + @Override + public void onClick(View view) { + mListener.onItemClick(mItems.get(getLayoutPosition())); + } + } + + public void addAll(List items) { + mItems.clear(); + mItems.addAll(items); + notifyDataSetChanged(); + } + + @Override + public int getItemCount() { + return mItems.size(); + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new ViewHolder(AdapterWordBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + holder.binding.text.setText(mItems.get(position)); + } +} diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/presenter/WordPresenter.java b/app/src/leanback/java/com/fongmi/android/tv/ui/presenter/WordPresenter.java deleted file mode 100644 index 6836ddd22..000000000 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/presenter/WordPresenter.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.fongmi.android.tv.ui.presenter; - -import android.view.LayoutInflater; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.leanback.widget.Presenter; - -import com.fongmi.android.tv.databinding.AdapterWordBinding; - -public class WordPresenter extends Presenter { - - private final OnClickListener mListener; - - public WordPresenter(OnClickListener listener) { - this.mListener = listener; - } - - public interface OnClickListener { - void onItemClick(String text); - } - - @Override - public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) { - return new ViewHolder(AdapterWordBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); - } - - @Override - public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object object) { - ViewHolder holder = (ViewHolder) viewHolder; - holder.binding.text.setText(object.toString()); - setOnClickListener(holder, view -> mListener.onItemClick(object.toString())); - } - - @Override - public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) { - } - - public static class ViewHolder extends Presenter.ViewHolder { - - private final AdapterWordBinding binding; - - public ViewHolder(@NonNull AdapterWordBinding binding) { - super(binding.getRoot()); - this.binding = binding; - } - } -} \ No newline at end of file diff --git a/app/src/leanback/res/layout/activity_search.xml b/app/src/leanback/res/layout/activity_search.xml index 88ace4952..0feb47b64 100644 --- a/app/src/leanback/res/layout/activity_search.xml +++ b/app/src/leanback/res/layout/activity_search.xml @@ -56,8 +56,10 @@ Players.get().web().start(parse.getUrl() + webUrl, callback)); diff --git a/app/src/main/java/com/fongmi/android/tv/utils/Prefers.java b/app/src/main/java/com/fongmi/android/tv/utils/Prefers.java index 454d8b12f..82d27c10e 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/Prefers.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/Prefers.java @@ -67,6 +67,14 @@ public class Prefers { Prefers.put("parse", parse); } + public static String getKeyword() { + return Prefers.getString("keyword"); + } + + public static void putKeyword(String keyword) { + Prefers.put("keyword", keyword); + } + public static int getScale() { return Prefers.getInt("scale"); }