diff --git a/app/src/main/java/com/github/tvbox/osc/ui/activity/SearchActivity.java b/app/src/main/java/com/github/tvbox/osc/ui/activity/SearchActivity.java index 762e7a76..00b04ad3 100644 --- a/app/src/main/java/com/github/tvbox/osc/ui/activity/SearchActivity.java +++ b/app/src/main/java/com/github/tvbox/osc/ui/activity/SearchActivity.java @@ -22,11 +22,20 @@ import com.github.tvbox.osc.bean.SourceBean; import com.github.tvbox.osc.event.RefreshEvent; import com.github.tvbox.osc.event.ServerEvent; import com.github.tvbox.osc.server.ControlManager; +import com.github.tvbox.osc.ui.adapter.PinyinAdapter; import com.github.tvbox.osc.ui.adapter.SearchAdapter; +import com.github.tvbox.osc.ui.dialog.RemoteDialog; import com.github.tvbox.osc.ui.tv.QRCodeGen; +import com.github.tvbox.osc.ui.tv.widget.SearchKeyboard; import com.github.tvbox.osc.util.FastClickCheckUtil; import com.github.tvbox.osc.viewmodel.SourceViewModel; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import com.lzy.okgo.OkGo; +import com.lzy.okgo.callback.AbsCallback; +import com.lzy.okgo.model.Response; import com.owen.tvrecyclerview.widget.TvRecyclerView; import com.owen.tvrecyclerview.widget.V7LinearLayoutManager; @@ -38,6 +47,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicInteger; /** * @author pj567 @@ -47,14 +57,16 @@ import java.util.concurrent.Executors; public class SearchActivity extends BaseActivity { private LinearLayout llLayout; private TvRecyclerView mGridView; + private TvRecyclerView mGridViewWord; SourceViewModel sourceViewModel; - private TextView tvName; private EditText etSearch; private TextView tvSearch; private TextView tvClear; + private SearchKeyboard keyboard; private TextView tvAddress; private ImageView ivQRCode; private SearchAdapter searchAdapter; + private PinyinAdapter wordAdapter; private String searchTitle = ""; @Override @@ -78,7 +90,18 @@ public class SearchActivity extends BaseActivity { tvAddress = findViewById(R.id.tvAddress); ivQRCode = findViewById(R.id.ivQRCode); mGridView = findViewById(R.id.mGridView); - tvName = findViewById(R.id.tvName); + keyboard = findViewById(R.id.keyBoardRoot); + mGridViewWord = findViewById(R.id.mGridViewWord); + mGridViewWord.setHasFixedSize(true); + mGridViewWord.setLayoutManager(new V7LinearLayoutManager(this.mContext, 1, false)); + wordAdapter = new PinyinAdapter(); + mGridViewWord.setAdapter(wordAdapter); + wordAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() { + @Override + public void onItemClick(BaseQuickAdapter adapter, View view, int position) { + search(wordAdapter.getItem(position)); + } + }); mGridView.setHasFixedSize(true); mGridView.setLayoutManager(new V7LinearLayoutManager(this.mContext, 1, false)); searchAdapter = new SearchAdapter(); @@ -115,6 +138,31 @@ public class SearchActivity extends BaseActivity { etSearch.setText(""); } }); + keyboard.setOnSearchKeyListener(new SearchKeyboard.OnSearchKeyListener() { + @Override + public void onSearchKey(int pos, String key) { + if (pos > 1) { + String text = etSearch.getText().toString().trim(); + text += key; + etSearch.setText(text); + if (text.length() > 0) { + loadRec(text); + } + } else if (pos == 1) { + String text = etSearch.getText().toString().trim(); + if (text.length() > 0) { + text = text.substring(0, text.length() - 1); + etSearch.setText(text); + } + if (text.length() > 0) { + loadRec(text); + } + } else if (pos == 0) { + RemoteDialog remoteDialog = new RemoteDialog().build(mContext); + remoteDialog.show(); + } + } + }); setLoadSir(llLayout); } @@ -122,6 +170,41 @@ public class SearchActivity extends BaseActivity { sourceViewModel = new ViewModelProvider(this).get(SourceViewModel.class); } + /** + * 拼音联想 + */ + private void loadRec(String key) { + OkGo.get("https://s.video.qq.com/smartbox") + .params("plat", 2) + .params("ver", 0) + .params("num", 10) + .params("otype", "json") + .params("query", key) + .execute(new AbsCallback() { + @Override + public void onSuccess(Response response) { + try { + ArrayList hots = new ArrayList<>(); + String result = response.body(); + JsonObject json = JsonParser.parseString(result.substring(result.indexOf("{"), result.lastIndexOf("}") + 1)).getAsJsonObject(); + JsonArray itemList = json.get("item").getAsJsonArray(); + for (JsonElement ele : itemList) { + JsonObject obj = (JsonObject) ele; + hots.add(obj.get("word").getAsString().trim()); + } + wordAdapter.setNewData(hots); + } catch (Throwable th) { + th.printStackTrace(); + } + } + + @Override + public String convertResponse(okhttp3.Response response) throws Throwable { + return response.body().string(); + } + }); + } + private void initData() { refreshQRCode(); Intent intent = getIntent(); @@ -130,6 +213,31 @@ public class SearchActivity extends BaseActivity { showLoading(); search(title); } + // 加载热词 + OkGo.get("https://node.video.qq.com/x/api/hot_mobilesearch") + .params("channdlId", "0") + .params("_", System.currentTimeMillis()) + .execute(new AbsCallback() { + @Override + public void onSuccess(Response response) { + try { + ArrayList hots = new ArrayList<>(); + JsonArray itemList = JsonParser.parseString(response.body()).getAsJsonObject().get("data").getAsJsonObject().get("itemList").getAsJsonArray(); + for (JsonElement ele : itemList) { + JsonObject obj = (JsonObject) ele; + hots.add(obj.get("title").getAsString().trim().replaceAll("<|>|《|》|-", "").split(" ")[0]); + } + wordAdapter.setNewData(hots); + } catch (Throwable th) { + th.printStackTrace(); + } + } + + @Override + public String convertResponse(okhttp3.Response response) throws Throwable { + return response.body().string(); + } + }); } private void refreshQRCode() { @@ -159,7 +267,6 @@ public class SearchActivity extends BaseActivity { } private void search(String title) { - tvName.setText(title); cancel(); showLoading(); this.searchTitle = title; @@ -168,50 +275,39 @@ public class SearchActivity extends BaseActivity { searchResult(); } - private final ExecutorService searchExecutorService = Executors.newFixedThreadPool(5); - private static final int maxThreadRun = 5; - private int threadRunCount = 0; - private final Object lockObj = new Object(); - private int allRunCount = 0; + private ExecutorService searchExecutorService = null; + private AtomicInteger allRunCount = new AtomicInteger(0); private void searchResult() { - synchronized (lockObj) { - threadRunCount = 0; + try { + if (searchExecutorService != null) { + searchExecutorService.shutdownNow(); + } + } catch (Throwable th) { + th.printStackTrace(); + } finally { + searchAdapter.setNewData(new ArrayList<>()); + allRunCount.set(0); } + searchExecutorService = Executors.newFixedThreadPool(5); List searchRequestList = new ArrayList<>(); searchRequestList.addAll(ApiConfig.get().getSourceBeanList()); SourceBean home = ApiConfig.get().getHomeSourceBean(); searchRequestList.remove(home); searchRequestList.add(0, home); - allRunCount = searchRequestList.size(); + ArrayList siteKey = new ArrayList<>(); for (SourceBean bean : searchRequestList) { if (!bean.isActive() || bean.isAddition()) { - allRunCount--; continue; } - String key = bean.getKey(); + siteKey.add(bean.getKey()); + allRunCount.incrementAndGet(); + } + for (String key : siteKey) { searchExecutorService.execute(new Runnable() { @Override public void run() { - while (true) { - int tempCount = 0; - synchronized (lockObj) { - tempCount = threadRunCount; - } - if (tempCount >= maxThreadRun) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } else { - break; - } - } - synchronized (lockObj) { - threadRunCount++; - } sourceViewModel.getSearch(key, searchTitle); } }); @@ -222,7 +318,8 @@ public class SearchActivity extends BaseActivity { if (absXml != null && absXml.movie != null && absXml.movie.videoList != null && absXml.movie.videoList.size() > 0) { List data = new ArrayList<>(); for (Movie.Video video : absXml.movie.videoList) { - data.add(video); + if (video.name.contains(searchTitle)) + data.add(video); } if (searchAdapter.getData().size() > 0) { searchAdapter.addData(data); @@ -233,15 +330,12 @@ public class SearchActivity extends BaseActivity { } } - synchronized (lockObj) { - threadRunCount--; - allRunCount--; - if (allRunCount <= 0) { - if (searchAdapter.getData().size() <= 0) { - showEmpty(); - } - cancel(); + int count = allRunCount.decrementAndGet(); + if (count <= 0) { + if (searchAdapter.getData().size() <= 0) { + showEmpty(); } + cancel(); } } diff --git a/app/src/main/java/com/github/tvbox/osc/ui/adapter/PinyinAdapter.java b/app/src/main/java/com/github/tvbox/osc/ui/adapter/PinyinAdapter.java new file mode 100644 index 00000000..889ed166 --- /dev/null +++ b/app/src/main/java/com/github/tvbox/osc/ui/adapter/PinyinAdapter.java @@ -0,0 +1,18 @@ +package com.github.tvbox.osc.ui.adapter; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.BaseViewHolder; +import com.github.tvbox.osc.R; + +import java.util.ArrayList; + +public class PinyinAdapter extends BaseQuickAdapter { + public PinyinAdapter() { + super(R.layout.item_search_word_layout_1, new ArrayList<>()); + } + + @Override + protected void convert(BaseViewHolder helper, String item) { + helper.setText(R.id.tvSearchWord, item); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/tvbox/osc/ui/adapter/SearchAdapter.java b/app/src/main/java/com/github/tvbox/osc/ui/adapter/SearchAdapter.java index 0523c6db..b771fbb6 100644 --- a/app/src/main/java/com/github/tvbox/osc/ui/adapter/SearchAdapter.java +++ b/app/src/main/java/com/github/tvbox/osc/ui/adapter/SearchAdapter.java @@ -20,6 +20,6 @@ public class SearchAdapter extends BaseQuickAdapter @Override protected void convert(BaseViewHolder helper, Movie.Video item) { - helper.setText(R.id.tvName, String.format("%s %s %s %s", ApiConfig.get().getSource(item.sourceKey).getName(), item.name, item.type, item.note)); + helper.setText(R.id.tvName, String.format("%s %s %s %s", ApiConfig.get().getSource(item.sourceKey).getName(), item.name, item.type == null ? "" : item.type, item.note == null ? "" : item.note)); } } \ No newline at end of file diff --git a/app/src/main/java/com/github/tvbox/osc/ui/tv/widget/SearchKeyboard.java b/app/src/main/java/com/github/tvbox/osc/ui/tv/widget/SearchKeyboard.java index 2b2544d2..c05ad0ce 100644 --- a/app/src/main/java/com/github/tvbox/osc/ui/tv/widget/SearchKeyboard.java +++ b/app/src/main/java/com/github/tvbox/osc/ui/tv/widget/SearchKeyboard.java @@ -1,12 +1,10 @@ package com.github.tvbox.osc.ui.tv.widget; import android.content.Context; -import android.text.Html; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.FrameLayout; -import android.widget.TextView; import androidx.annotation.AttrRes; import androidx.annotation.NonNull; @@ -32,12 +30,8 @@ import java.util.List; */ public class SearchKeyboard extends FrameLayout { private RecyclerView mRecyclerView; - private List keys = Arrays.asList("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M" - , "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9" - , "0", "删除", "清空"); + private List keys = Arrays.asList("远程搜索", "删除", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"); private List keyboardList = new ArrayList<>(); - private TextView hint; - private TextView search; private OnSearchKeyListener searchKeyListener; private OnFocusChangeListener focusChangeListener = new OnFocusChangeListener() { @Override @@ -64,9 +58,7 @@ public class SearchKeyboard extends FrameLayout { private void initView() { View view = LayoutInflater.from(getContext()).inflate(R.layout.keyboard_layout, this); mRecyclerView = (RecyclerView) view.findViewById(R.id.mRecyclerView); - hint = (TextView) view.findViewById(R.id.hint); - search = (TextView) view.findViewById(R.id.search); - GridLayoutManager manager = new GridLayoutManager(getContext(), 5); + GridLayoutManager manager = new GridLayoutManager(getContext(), 6); mRecyclerView.setLayoutManager(manager); mRecyclerView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() { @Override @@ -81,45 +73,29 @@ public class SearchKeyboard extends FrameLayout { } }); - String html = "请输入全拼或者首字母查找影片
首字母如:" + "“金刚川”输入“JGC”" + - "
部分影片可能搜索不出来"; - hint.setText(Html.fromHtml(html)); int size = keys.size(); for (int i = 0; i < size; i++) { - if (i < size - 2) { - keyboardList.add(new Keyboard(1, keys.get(i))); - } else { - keyboardList.add(new Keyboard(2, keys.get(i))); - } + keyboardList.add(new Keyboard(1, keys.get(i))); } final KeyboardAdapter adapter = new KeyboardAdapter(keyboardList); mRecyclerView.setAdapter(adapter); adapter.setSpanSizeLookup(new BaseQuickAdapter.SpanSizeLookup() { @Override public int getSpanSize(GridLayoutManager gridLayoutManager, int position) { - if (position == adapter.getData().size() - 2 || position == adapter.getData().size() - 1) { - return 2; - } + if (position == 0) + return 3; + else if (position == 1) + return 3; return 1; } - }); adapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() { @Override public void onItemClick(BaseQuickAdapter adapter, View view, int position) { Keyboard keyboard = (Keyboard) adapter.getItem(position); - String text = search.getText().toString(); - if (position == adapter.getData().size() - 1) { - text = ""; - } else if (position == adapter.getData().size() - 2) { - text = text.substring(0, text.length() - 1); - } else { - text += keyboard.getKey(); - } - search.setText(text); if (searchKeyListener != null) { - searchKeyListener.onSearchKey(text); + searchKeyListener.onSearchKey(position, keyboard.getKey()); } } }); @@ -177,6 +153,6 @@ public class SearchKeyboard extends FrameLayout { } public interface OnSearchKeyListener { - void onSearchKey(String key); + void onSearchKey(int pos, String key); } } \ No newline at end of file diff --git a/app/src/main/java/com/github/tvbox/osc/viewmodel/SourceViewModel.java b/app/src/main/java/com/github/tvbox/osc/viewmodel/SourceViewModel.java index e49568cf..2b4a8eb6 100644 --- a/app/src/main/java/com/github/tvbox/osc/viewmodel/SourceViewModel.java +++ b/app/src/main/java/com/github/tvbox/osc/viewmodel/SourceViewModel.java @@ -217,17 +217,12 @@ public class SourceViewModel extends ViewModel { SourceBean sourceBean = ApiConfig.get().getSource(sourceKey); int type = sourceBean.getType(); if (type == 3) { - spThreadPool.execute(new Runnable() { - @Override - public void run() { - try { - Spider sp = ApiConfig.get().getCSP(sourceBean); - json(searchResult, sp.searchContent(wd, false), sourceBean.getKey()); - } catch (Throwable th) { - th.printStackTrace(); - } - } - }); + try { + Spider sp = ApiConfig.get().getCSP(sourceBean); + json(searchResult, sp.searchContent(wd, false), sourceBean.getKey()); + } catch (Throwable th) { + th.printStackTrace(); + } } else if (type == 0 || type == 1) { OkGo.get(sourceBean.getApi()) .params("wd", wd) @@ -270,17 +265,12 @@ public class SourceViewModel extends ViewModel { SourceBean sourceBean = ApiConfig.get().getSource(sourceKey); int type = sourceBean.getType(); if (type == 3) { - spThreadPool.execute(new Runnable() { - @Override - public void run() { - try { - Spider sp = ApiConfig.get().getCSP(sourceBean); - json(quickSearchResult, sp.searchContent(wd, true), sourceBean.getKey()); - } catch (Throwable th) { - th.printStackTrace(); - } - } - }); + try { + Spider sp = ApiConfig.get().getCSP(sourceBean); + json(quickSearchResult, sp.searchContent(wd, true), sourceBean.getKey()); + } catch (Throwable th) { + th.printStackTrace(); + } } else if (type == 0 || type == 1) { OkGo.get(sourceBean.getApi()) .params("wd", wd) diff --git a/app/src/main/res/drawable/search_focus.xml b/app/src/main/res/drawable/search_focus.xml index 621a719d..6e4fa751 100644 --- a/app/src/main/res/drawable/search_focus.xml +++ b/app/src/main/res/drawable/search_focus.xml @@ -2,15 +2,15 @@ - - - + + + - - + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_search.xml b/app/src/main/res/layout/activity_search.xml index 3b91479e..0694ca21 100644 --- a/app/src/main/res/layout/activity_search.xml +++ b/app/src/main/res/layout/activity_search.xml @@ -6,130 +6,145 @@ android:orientation="horizontal"> - - + android:orientation="vertical" + android:padding="@dimen/vs_20"> + android:textSize="@dimen/ts_20" /> + android:textSize="@dimen/ts_20" /> + android:textSize="@dimen/ts_20" /> - + + + android:orientation="vertical"> - + + + + + android:paddingTop="@dimen/vs_20" + android:paddingBottom="@dimen/vs_20"> + android:textSize="@dimen/ts_22" /> + + + + + + app:tv_verticalSpacingWithMargins="@dimen/vs_5" /> \ No newline at end of file diff --git a/app/src/main/res/layout/item_keyboard_1.xml b/app/src/main/res/layout/item_keyboard_1.xml index 32b9f3ed..59c35382 100644 --- a/app/src/main/res/layout/item_keyboard_1.xml +++ b/app/src/main/res/layout/item_keyboard_1.xml @@ -1,17 +1,19 @@ + android:layout_width="match_parent" + android:layout_height="@dimen/vs_40" + android:layout_gravity="center" + android:layout_margin="@dimen/vs_4" + android:background="@drawable/search_focus" + android:focusable="true"> + android:textSize="@dimen/ts_22" /> \ No newline at end of file diff --git a/app/src/main/res/layout/item_search_layout.xml b/app/src/main/res/layout/item_search_layout.xml index ac515759..581449f7 100644 --- a/app/src/main/res/layout/item_search_layout.xml +++ b/app/src/main/res/layout/item_search_layout.xml @@ -3,18 +3,16 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/source_focus" - android:focusable="true" - android:focusableInTouchMode="true"> + android:focusable="true"> + android:textSize="@dimen/ts_20" /> \ No newline at end of file diff --git a/app/src/main/res/layout/item_search_word_layout.xml b/app/src/main/res/layout/item_search_word_layout.xml index 25067cff..37e2004d 100644 --- a/app/src/main/res/layout/item_search_word_layout.xml +++ b/app/src/main/res/layout/item_search_word_layout.xml @@ -3,14 +3,14 @@ android:id="@+id/tvSearchWord" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_margin="5mm" + android:layout_margin="@dimen/vs_5" android:background="@drawable/source_focus" android:ellipsize="end" android:focusable="true" android:focusableInTouchMode="true" android:gravity="center_vertical" - android:paddingLeft="10mm" - android:paddingRight="10mm" + android:paddingLeft="@dimen/vs_10" + android:paddingRight="@dimen/vs_10" android:singleLine="true" android:textColor="@android:color/white" - android:textSize="20mm" /> + android:textSize="@dimen/ts_20" /> diff --git a/app/src/main/res/layout/item_search_word_layout_1.xml b/app/src/main/res/layout/item_search_word_layout_1.xml new file mode 100644 index 00000000..5eda4efa --- /dev/null +++ b/app/src/main/res/layout/item_search_word_layout_1.xml @@ -0,0 +1,15 @@ + + diff --git a/app/src/main/res/layout/keyboard_layout.xml b/app/src/main/res/layout/keyboard_layout.xml index e94c95fb..9cb5347e 100644 --- a/app/src/main/res/layout/keyboard_layout.xml +++ b/app/src/main/res/layout/keyboard_layout.xml @@ -1,48 +1,12 @@ - - - - - - - + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginLeft="@dimen/vs_4_" + android:layout_marginRight="@dimen/vs_4_"> - - + android:layout_width="match_parent" + android:layout_height="wrap_content" /> \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index d3ee886e..15c7f75a 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -17,6 +17,7 @@ 8mm 20mm + -4mm -20mm -60mm