New search ui

pull/21/head
FongMi 4 years ago
parent d999e37da5
commit 4daecbe1a7
  1. 164
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/SearchActivity.java
  2. 96
      app/src/leanback/java/com/fongmi/android/tv/ui/adapter/KeyboardAdapter.java
  3. 35
      app/src/leanback/java/com/fongmi/android/tv/ui/custom/CustomKeyboard.java
  4. 16
      app/src/leanback/java/com/fongmi/android/tv/ui/custom/CustomVerticalGridView.java
  5. 36
      app/src/leanback/java/com/fongmi/android/tv/ui/custom/SpaceItemDecoration.java
  6. 63
      app/src/leanback/java/com/fongmi/android/tv/ui/presenter/KeyboardPresenter.java
  7. 52
      app/src/leanback/java/com/fongmi/android/tv/ui/presenter/WordPresenter.java
  8. 5
      app/src/leanback/res/drawable/ic_mic.xml
  9. 6
      app/src/leanback/res/drawable/selector_filter.xml
  10. 5
      app/src/leanback/res/drawable/selector_keyboard.xml
  11. 5
      app/src/leanback/res/drawable/selector_mic.xml
  12. 13
      app/src/leanback/res/drawable/shape_keyboard_focused.xml
  13. 9
      app/src/leanback/res/drawable/shape_keyboard_normal.xml
  14. 11
      app/src/leanback/res/drawable/shape_mic_focused.xml
  15. 7
      app/src/leanback/res/drawable/shape_mic_normal.xml
  16. 114
      app/src/leanback/res/layout/activity_search.xml
  17. 4
      app/src/leanback/res/layout/adapter_episode.xml
  18. 2
      app/src/leanback/res/layout/adapter_filter.xml
  19. 2
      app/src/leanback/res/layout/adapter_flag.xml
  20. 2
      app/src/leanback/res/layout/adapter_group.xml
  21. 27
      app/src/leanback/res/layout/adapter_keyboard.xml
  22. 11
      app/src/leanback/res/layout/adapter_keyboard_icon.xml
  23. 14
      app/src/leanback/res/layout/adapter_keyboard_text.xml
  24. 2
      app/src/leanback/res/layout/adapter_site.xml
  25. 14
      app/src/leanback/res/layout/adapter_word.xml
  26. 2
      app/src/leanback/res/layout/view_controller_bottom.xml
  27. 47
      app/src/main/java/com/fongmi/android/tv/bean/Hot.java
  28. 37
      app/src/main/java/com/fongmi/android/tv/bean/Suggest.java
  29. 2
      app/src/main/java/com/fongmi/android/tv/net/Callback.java

@ -8,9 +8,9 @@ import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import androidx.annotation.NonNull;
import androidx.leanback.widget.ArrayObjectAdapter;
import androidx.leanback.widget.ItemBridgeAdapter;
import androidx.leanback.widget.ListRow;
@ -18,26 +18,23 @@ import androidx.lifecycle.ViewModelProvider;
import androidx.viewbinding.ViewBinding;
import com.fongmi.android.tv.api.ApiConfig;
import com.fongmi.android.tv.bean.Filter;
import com.fongmi.android.tv.bean.Hot;
import com.fongmi.android.tv.bean.Result;
import com.fongmi.android.tv.bean.Site;
import com.fongmi.android.tv.bean.Suggest;
import com.fongmi.android.tv.bean.Vod;
import com.fongmi.android.tv.databinding.ActivitySearchBinding;
import com.fongmi.android.tv.model.SiteViewModel;
import com.fongmi.android.tv.net.Callback;
import com.fongmi.android.tv.net.OKHttp;
import com.fongmi.android.tv.ui.custom.CustomKeyboard;
import com.fongmi.android.tv.ui.custom.CustomRowPresenter;
import com.fongmi.android.tv.ui.custom.CustomSelector;
import com.fongmi.android.tv.ui.presenter.EpisodePresenter;
import com.fongmi.android.tv.ui.presenter.FilterPresenter;
import com.fongmi.android.tv.ui.presenter.TitlePresenter;
import com.fongmi.android.tv.ui.presenter.VodPresenter;
import com.fongmi.android.tv.ui.presenter.WordPresenter;
import com.fongmi.android.tv.utils.ResUtil;
import com.google.common.collect.Lists;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.IOException;
import java.util.ArrayList;
@ -45,17 +42,18 @@ import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SearchActivity extends BaseActivity implements VodPresenter.OnClickListener {
import okhttp3.Call;
import okhttp3.Response;
public class SearchActivity extends BaseActivity implements VodPresenter.OnClickListener, WordPresenter.OnClickListener, TextWatcher {
private ActivitySearchBinding mBinding;
private SiteViewModel mSiteViewModel;
private ArrayObjectAdapter mWordAdapter;
private ArrayObjectAdapter mAdapter;
private ExecutorService mService;
private List<Site> mSites;
private ArrayObjectAdapter recommendWordAdapter;
private String searchKeyword = "";
FilterPresenter filterPresenter;
private Handler handler = new Handler(Looper.getMainLooper());
private Handler mHandler;
private String getKeyword() {
return getIntent().getStringExtra("keyword");
@ -86,48 +84,26 @@ public class SearchActivity extends BaseActivity implements VodPresenter.OnClick
@Override
protected void initView() {
mHandler = new Handler(Looper.getMainLooper());
CustomKeyboard.init(mBinding);
mBinding.keyword.requestFocus();
setRecyclerView();
setViewModel();
checkKeyword();
setSite();
getHot();
}
@Override
protected void initEvent() {
mBinding.search.setOnClickListener(view -> {
searchKeyword = mBinding.keyword.getText().toString().trim();
onSearch();
});
mBinding.keyword.addTextChangedListener(this);
mBinding.search.setOnClickListener(view -> onSearch());
mBinding.clear.setOnClickListener(view -> mBinding.keyword.setText(""));
mBinding.remote.setOnClickListener(view -> PushActivity.start(this));
mBinding.keyword.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
loadRecommendKey(editable);
}
});
mBinding.keyword.setOnEditorActionListener((textView, actionId, event) -> {
if (actionId == EditorInfo.IME_ACTION_DONE) mBinding.search.performClick();
return true;
});
filterPresenter.setOnClickListener(this::recommendWordClick);
}
private void recommendWordClick(String s, Filter.Value value) {
searchKeyword = value.getV();
onSearch();
}
private void setRecyclerView() {
@ -136,10 +112,8 @@ public class SearchActivity extends BaseActivity implements VodPresenter.OnClick
selector.addPresenter(ListRow.class, new CustomRowPresenter(16), VodPresenter.class);
mBinding.recycler.setVerticalSpacing(ResUtil.dp2px(16));
mBinding.recycler.setAdapter(new ItemBridgeAdapter(mAdapter = new ArrayObjectAdapter(selector)));
mBinding.recommendWordGrid.setHorizontalSpacing(ResUtil.dp2px(8));
mBinding.recommendWordGrid.setRowHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
mBinding.recommendWordGrid.setAdapter(new ItemBridgeAdapter(recommendWordAdapter =
new ArrayObjectAdapter(filterPresenter = new FilterPresenter("recommend_word"))));
mBinding.word.setVerticalSpacing(ResUtil.dp2px(16));
mBinding.word.setAdapter(new ItemBridgeAdapter(mWordAdapter = new ArrayObjectAdapter(new WordPresenter(this))));
}
private void setViewModel() {
@ -149,23 +123,21 @@ public class SearchActivity extends BaseActivity implements VodPresenter.OnClick
});
}
private void setSite() {
mSites = new ArrayList<>();
for (Site site : ApiConfig.get().getSites()) if (site.isSearchable()) mSites.add(site);
if (!mSites.contains(ApiConfig.get().getHome())) return;
mSites.remove(ApiConfig.get().getHome());
mSites.add(0, ApiConfig.get().getHome());
}
private void checkKeyword() {
String externalKeyword = getKeyword();
if (externalKeyword.isEmpty()) return;
if (getKeyword().isEmpty()) return;
stopSearch();
mAdapter.clear();
mBinding.keyword.setText(externalKeyword);
mBinding.keyword.setSelection(mBinding.keyword.length());
searchKeyword = externalKeyword;
new Handler().postDelayed(this::onSearch, 250);
mBinding.keyword.setText(getKeyword());
mHandler.postDelayed(this::onSearch, 250);
}
private void setSite() {
mSites = new ArrayList<>();
for (Site site : ApiConfig.get().getSites()) if (site.isSearchable()) mSites.add(site);
Site home = ApiConfig.get().getHome();
if (!mSites.contains(home)) return;
mSites.remove(home);
mSites.add(0, home);
}
private void addVideo(Result result) {
@ -181,9 +153,11 @@ public class SearchActivity extends BaseActivity implements VodPresenter.OnClick
}
private void onSearch() {
if (TextUtils.isEmpty(searchKeyword)) return;
String keyword = mBinding.keyword.getText().toString().trim();
mBinding.keyword.setSelection(mBinding.keyword.length());
if (TextUtils.isEmpty(keyword)) return;
mService = Executors.newFixedThreadPool(5);
for (Site site : mSites) mService.execute(() -> mSiteViewModel.searchContent(site.getKey(), searchKeyword));
for (Site site : mSites) mService.execute(() -> mSiteViewModel.searchContent(site.getKey(), keyword));
showProgress();
}
@ -213,6 +187,46 @@ public class SearchActivity extends BaseActivity implements VodPresenter.OnClick
DetailActivity.start(this, item.getSite().getKey(), item.getVodId());
}
@Override
public void onItemClick(String text) {
mBinding.keyword.setText(text);
onSearch();
}
private void getHot() {
OKHttp.newCall("https://node.video.qq.com/x/api/hot_mobilesearch?channdlId=0").enqueue(new Callback() {
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
List<String> items = Hot.get(response.body().string());
mHandler.post(() -> mWordAdapter.setItems(items, null));
}
});
}
private void getSuggest(String text) {
OKHttp.newCall("https://suggest.video.iqiyi.com/?if=mobile&key=" + text).enqueue(new Callback() {
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
List<String> items = Suggest.get(response.body().string());
mHandler.post(() -> mWordAdapter.setItems(items, null));
}
});
}
@Override
public void afterTextChanged(Editable s) {
if (s.toString().isEmpty()) getHot();
else getSuggest(s.toString());
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onBackPressed() {
if (isProgressVisible()) {
@ -229,36 +243,4 @@ public class SearchActivity extends BaseActivity implements VodPresenter.OnClick
super.onDestroy();
stopSearch();
}
private void loadRecommendKey(CharSequence entered) {
mBinding.recommendWordGrid.setVisibility(View.GONE);
if(TextUtils.isEmpty(entered) || searchKeyword.equals(entered))
return;
recommendWordAdapter.clear();
new Thread(() -> {
try {
String result = OKHttp.newCall("https://suggest.video.iqiyi.com/?if=mobile&key=" + entered).execute().body().string();
JsonObject json = JsonParser.parseString(result.substring(result.indexOf("{"), result.lastIndexOf("}") + 1)).getAsJsonObject();
JsonArray itemList = json.get("data").getAsJsonArray();
JsonObject filterMapped = (JsonObject) JsonParser.parseString("{\"key\":\"recommend_word\",\"name\":\"recommend_word\",value:[]}");
for (JsonElement ele : itemList) {
JsonObject obj = (JsonObject) ele;
String word = obj.get("name").getAsString().trim();
JsonObject converted = new JsonObject();
converted.addProperty("n", word);
converted.addProperty("v", word);
filterMapped.getAsJsonArray("value").add(converted);
}
handler.post(new Runnable() {
@Override
public void run() {
recommendWordAdapter.addAll(0, Filter.objectFrom(filterMapped).getValue());
mBinding.recommendWordGrid.setVisibility(View.VISIBLE);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
}

@ -0,0 +1,96 @@
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.R;
import com.fongmi.android.tv.databinding.AdapterKeyboardIconBinding;
import com.fongmi.android.tv.databinding.AdapterKeyboardTextBinding;
import java.util.Arrays;
import java.util.List;
public class KeyboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final OnClickListener mListener;
private final List<Object> mItems;
public KeyboardAdapter(OnClickListener listener) {
this.mItems = Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "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", R.drawable.ic_keyboard_left, R.drawable.ic_keyboard_right, R.drawable.ic_keyboard_back, R.drawable.ic_keyboard_enter);
this.mListener = listener;
}
public interface OnClickListener {
void onTextClick(String text);
void onIconClick(int resId);
}
class TextHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final AdapterKeyboardTextBinding binding;
TextHolder(@NonNull AdapterKeyboardTextBinding binding) {
super(binding.getRoot());
this.binding = binding;
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
mListener.onTextClick(mItems.get(getLayoutPosition()).toString());
}
}
class IconHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final AdapterKeyboardIconBinding binding;
IconHolder(@NonNull AdapterKeyboardIconBinding binding) {
super(binding.getRoot());
this.binding = binding;
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
mListener.onIconClick((int) mItems.get(getLayoutPosition()));
}
}
@Override
public int getItemViewType(int position) {
return mItems.get(position) instanceof String ? 0 : 1;
}
@Override
public int getItemCount() {
return mItems.size();
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == 0) return new TextHolder(AdapterKeyboardTextBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
else return new IconHolder(AdapterKeyboardIconBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
switch (getItemViewType(position)) {
case 0:
TextHolder text = (TextHolder) holder;
text.binding.text.setText(mItems.get(position).toString());
break;
case 1:
IconHolder icon = (IconHolder) holder;
icon.binding.icon.setImageResource((int) mItems.get(position));
break;
}
}
}

@ -2,21 +2,13 @@ package com.fongmi.android.tv.ui.custom;
import android.annotation.SuppressLint;
import androidx.leanback.widget.ArrayObjectAdapter;
import androidx.leanback.widget.ItemBridgeAdapter;
import androidx.leanback.widget.ListRow;
import androidx.recyclerview.widget.GridLayoutManager;
import com.fongmi.android.tv.R;
import com.fongmi.android.tv.databinding.ActivitySearchBinding;
import com.fongmi.android.tv.ui.presenter.KeyboardPresenter;
import com.fongmi.android.tv.utils.ResUtil;
import com.google.common.collect.Lists;
import com.fongmi.android.tv.ui.adapter.KeyboardAdapter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CustomKeyboard implements KeyboardPresenter.OnClickListener {
public class CustomKeyboard implements KeyboardAdapter.OnClickListener {
private final ActivitySearchBinding binding;
@ -29,23 +21,10 @@ public class CustomKeyboard implements KeyboardPresenter.OnClickListener {
}
private void initView() {
CustomSelector selector = new CustomSelector();
selector.addPresenter(ListRow.class, new CustomRowPresenter(12), KeyboardPresenter.class);
ArrayObjectAdapter adapter = new ArrayObjectAdapter(selector);
binding.keyboard.setVerticalSpacing(ResUtil.dp2px(12));
binding.keyboard.setAdapter(new ItemBridgeAdapter(adapter));
adapter.addAll(adapter.size(), getRows());
}
private List<ListRow> getRows() {
List<Object> keys = Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "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", R.drawable.ic_keyboard_left, R.drawable.ic_keyboard_right, R.drawable.ic_keyboard_back, R.drawable.ic_keyboard_enter);
List<ListRow> rows = new ArrayList<>();
for (List<Object> items : Lists.partition(keys, 10)) {
ArrayObjectAdapter adapter = new ArrayObjectAdapter(new KeyboardPresenter(this));
adapter.addAll(0, items);
rows.add(new ListRow(adapter));
}
return rows;
binding.keyboard.setHasFixedSize(true);
binding.keyboard.setLayoutManager(new GridLayoutManager(binding.getRoot().getContext(), 10));
binding.keyboard.addItemDecoration(new SpaceItemDecoration(10, 8));
binding.keyboard.setAdapter(new KeyboardAdapter(this));
}
@Override

@ -13,7 +13,7 @@ import androidx.recyclerview.widget.RecyclerView;
public class CustomVerticalGridView extends VerticalGridView {
private View mTabView;
private View tabView;
private boolean pressUp;
private boolean pressDown;
@ -35,18 +35,18 @@ public class CustomVerticalGridView extends VerticalGridView {
setOnChildViewHolderSelectedListener(new OnChildViewHolderSelectedListener() {
@Override
public void onChildViewHolderSelected(@NonNull RecyclerView parent, @Nullable ViewHolder child, int position, int subposition) {
if (mTabView == null) return;
if (tabView == null) return;
if (pressUp && position == 0) {
mTabView.setVisibility(View.VISIBLE);
tabView.setVisibility(View.VISIBLE);
} else if (pressDown && position == 1) {
mTabView.setVisibility(View.GONE);
tabView.setVisibility(View.GONE);
}
}
});
}
public void setTabView(View tabView) {
this.mTabView = tabView;
this.tabView = tabView;
}
@Override
@ -69,9 +69,9 @@ public class CustomVerticalGridView extends VerticalGridView {
}
public boolean moveToTop() {
if (mTabView == null) return false;
mTabView.setVisibility(View.VISIBLE);
mTabView.requestFocus();
if (tabView == null) return false;
tabView.setVisibility(View.VISIBLE);
tabView.requestFocus();
scrollToPosition(0);
return true;
}

@ -0,0 +1,36 @@
package com.fongmi.android.tv.ui.custom;
import android.graphics.Rect;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.fongmi.android.tv.utils.ResUtil;
public class SpaceItemDecoration extends RecyclerView.ItemDecoration {
private final int spanCount;
private final int spacing;
public SpaceItemDecoration(int spanCount, int spacing) {
this.spanCount = spanCount;
this.spacing = ResUtil.dp2px(spacing);
}
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, RecyclerView parent, @NonNull RecyclerView.State state) {
int position = parent.getChildAdapterPosition(view);
if (position >= 0) {
int column = position % spanCount;
outRect.left = column * spacing / spanCount;
outRect.right = spacing - (column + 1) * spacing / spanCount;
if (position >= spanCount) outRect.top = spacing;
} else {
outRect.left = 0;
outRect.right = 0;
outRect.top = 0;
outRect.bottom = 0;
}
}
}

@ -1,63 +0,0 @@
package com.fongmi.android.tv.ui.presenter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.leanback.widget.Presenter;
import com.fongmi.android.tv.databinding.AdapterKeyboardBinding;
public class KeyboardPresenter extends Presenter {
private final OnClickListener mListener;
public KeyboardPresenter(OnClickListener listener) {
this.mListener = listener;
}
public interface OnClickListener {
void onTextClick(String text);
void onIconClick(int resId);
}
@Override
public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) {
return new ViewHolder(AdapterKeyboardBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
}
@Override
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object object) {
ViewHolder holder = (ViewHolder) viewHolder;
if (object instanceof String) {
String text = (String) object;
holder.binding.text.setText(text);
holder.binding.icon.setVisibility(View.GONE);
holder.binding.text.setVisibility(View.VISIBLE);
setOnClickListener(holder, view -> mListener.onTextClick(text));
} else {
int resId = (int) object;
holder.binding.icon.setImageResource(resId);
holder.binding.text.setVisibility(View.GONE);
holder.binding.icon.setVisibility(View.VISIBLE);
setOnClickListener(holder, view -> mListener.onIconClick(resId));
}
}
@Override
public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
}
public static class ViewHolder extends Presenter.ViewHolder {
private final AdapterKeyboardBinding binding;
public ViewHolder(@NonNull AdapterKeyboardBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
}

@ -0,0 +1,52 @@
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 OnClickListener mListener;
public WordPresenter(OnClickListener listener) {
this.mListener = listener;
}
public interface OnClickListener {
void onItemClick(String text);
}
public void setOnClickListener(OnClickListener listener) {
this.mListener = listener;
}
@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;
}
}
}

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,14c1.66,0 2.99,-1.34 2.99,-3L15,5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM17.3,11c0,3 -2.54,5.1 -5.3,5.1S6.7,14 6.7,11L5,11c0,3.41 2.72,6.23 6,6.72L11,21h2v-3.28c3.28,-0.48 6,-3.3 6,-6.72h-1.7z"/>
</vector>

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/shape_type_focused" android:state_focused="true" />
<item android:drawable="@drawable/shape_type_activated" android:state_activated="true" />
<item android:drawable="@drawable/shape_type_normal" />
</selector>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/shape_keyboard_focused" android:state_focused="true" />
<item android:drawable="@drawable/shape_keyboard_normal" />
</selector>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/shape_mic_focused" android:state_focused="true" />
<item android:drawable="@drawable/shape_mic_normal" />
</selector>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/black_30" />
<corners android:radius="4dp" />
<stroke
android:width="1dp"
android:color="@color/white" />
</shape>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/black_20" />
<corners android:radius="4dp" />
</shape>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/black_30" />
<stroke
android:width="1dp"
android:color="@color/white" />
</shape>

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/black_20" />
</shape>

@ -1,59 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true">
<com.fongmi.android.tv.ui.custom.ProgressLayout
android:id="@+id/progressLayout"
<RelativeLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
android:layout_height="match_parent">
<androidx.leanback.widget.VerticalGridView
android:id="@+id/recycler"
<com.fongmi.android.tv.ui.custom.CustomEditText
android:id="@+id/keyword"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:hint="@string/search_hint"
android:imeOptions="actionDone"
android:inputType="textCapCharacters|textAutoCorrect|textAutoComplete"
android:letterSpacing="0.05"
android:maxLength="50"
android:paddingStart="24dp"
android:paddingTop="24dp"
android:paddingEnd="24dp"
android:paddingBottom="12dp"
android:singleLine="true"
android:textColor="@color/white"
android:textColorHint="@color/white"
android:textSize="24sp" />
<androidx.leanback.widget.VerticalGridView
android:id="@+id/word"
android:layout_width="240dp"
android:layout_height="wrap_content"
android:layout_below="@+id/keyword"
android:clipChildren="false"
android:clipToPadding="false"
android:padding="24dp"
android:paddingStart="24dp"
android:paddingTop="12dp"
android:paddingEnd="12dp"
android:paddingBottom="24dp"
app:focusOutEnd="true"
app:focusOutFront="true" />
</com.fongmi.android.tv.ui.custom.ProgressLayout>
<RelativeLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/keyboard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/keyword"
android:layout_toEndOf="@+id/word"
android:clipChildren="false"
android:clipToPadding="false"
android:padding="12dp" />
<LinearLayout
android:id="@+id/search_bar"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/keyboard"
android:layout_alignStart="@+id/keyboard"
android:layout_alignEnd="@+id/keyboard"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:layout_marginTop="12dp"
android:gravity="center"
android:orientation="horizontal">
<com.fongmi.android.tv.ui.custom.CustomEditText
android:id="@+id/keyword"
android:layout_width="0dp"
android:layout_height="wrap_content"
<ImageView
android:id="@+id/mic"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:layout_marginEnd="16dp"
android:layout_weight="1"
android:background="@drawable/selector_item"
android:hint="@string/search_hint"
android:imeOptions="actionDone"
android:inputType="textCapCharacters|textAutoCorrect|textAutoComplete"
android:maxLength="30"
android:singleLine="true"
android:textColor="@color/white"
android:textColorHint="@color/white"
android:textSize="18sp" />
android:background="@drawable/selector_mic"
android:focusable="true"
android:focusableInTouchMode="true"
android:scaleType="center"
android:src="@drawable/ic_mic" />
<TextView
android:id="@+id/search"
@ -91,26 +111,24 @@
android:textSize="18sp" />
</LinearLayout>
</RelativeLayout>
<com.fongmi.android.tv.ui.custom.CustomHorizontalGridView
android:id="@+id/recommend_word_grid"
android:layout_width="556dp"
android:layout_height="wrap_content"
android:layout_below="@id/search_bar"
android:layout_marginTop="4mm"
android:layout_marginBottom="4mm"
android:visibility="gone" />
<com.fongmi.android.tv.ui.custom.ProgressLayout
android:id="@+id/progressLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<androidx.leanback.widget.VerticalGridView
android:id="@+id/keyboard"
android:layout_width="556dp"
android:layout_height="244dp"
android:layout_below="@id/recommend_word_grid"
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:padding="24dp"
app:focusOutEnd="true"
app:focusOutFront="true" />
</RelativeLayout>
</RelativeLayout>
</com.fongmi.android.tv.ui.custom.ProgressLayout>
</FrameLayout>

@ -10,8 +10,8 @@
android:focusableInTouchMode="true"
android:gravity="center"
android:maxEms="10"
android:nextFocusUp="@+id/flag"
android:nextFocusDown="@+id/group"
android:nextFocusUp="@id/flag"
android:nextFocusDown="@id/group"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="16sp"

@ -4,7 +4,7 @@
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/selector_filter"
android:background="@drawable/selector_type"
android:focusable="true"
android:focusableInTouchMode="true"
android:textColor="@color/white"

@ -8,7 +8,7 @@
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center"
android:nextFocusDown="@+id/episode"
android:nextFocusDown="@id/episode"
android:textColor="@color/white"
android:textSize="16sp"
tools:text="泥巴" />

@ -8,7 +8,7 @@
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center"
android:nextFocusUp="@+id/episode"
android:nextFocusUp="@id/episode"
android:textColor="@color/white"
android:textSize="16sp"
tools:text="11" />

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@drawable/selector_item"
android:focusable="true"
android:focusableInTouchMode="true"
android:padding="8dp">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="@color/white"
android:textSize="16sp"
tools:text="0" />
<ImageView
android:id="@+id/icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:src="@drawable/ic_keyboard_back" />
</FrameLayout>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/icon"
android:layout_width="44dp"
android:layout_height="44dp"
android:background="@drawable/selector_keyboard"
android:focusable="true"
android:focusableInTouchMode="true"
android:padding="6dp"
tools:src="@drawable/ic_keyboard_back" />

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/text"
android:layout_width="44dp"
android:layout_height="44dp"
android:background="@drawable/selector_keyboard"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center"
android:padding="6dp"
android:textColor="@color/white"
android:textSize="16sp"
tools:text="0" />

@ -11,4 +11,4 @@
android:singleLine="true"
android:textColor="@color/white"
android:textSize="18sp"
tools:text="泥巴影院" />
tools:text="泥巴" />

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/selector_type"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusLeft="@id/word"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="16sp"
tools:text="推薦" />

@ -179,7 +179,7 @@
android:focusableInTouchMode="true"
android:nextFocusLeft="@id/exo_progress"
android:nextFocusRight="@id/exo_progress"
android:nextFocusUp="@+id/next"
android:nextFocusUp="@id/next"
android:nextFocusDown="@id/exo_progress"
app:buffered_color="@color/grey_700"
app:played_color="@color/blue_700"

@ -0,0 +1,47 @@
package com.fongmi.android.tv.bean;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
public class Hot {
@SerializedName("data")
private Data data;
private static Hot objectFrom(String str) {
return new Gson().fromJson(str, Hot.class);
}
public static List<String> get(String str) {
List<String> items = new ArrayList<>();
for (Data.Item item : objectFrom(str).getData().getItemList()) items.add(item.getTitle());
return items;
}
private Data getData() {
return data;
}
static class Data {
@SerializedName("itemList")
private List<Item> itemList;
public List<Item> getItemList() {
return itemList;
}
static class Item {
@SerializedName("title")
private String title;
public String getTitle() {
return title;
}
}
}
}

@ -0,0 +1,37 @@
package com.fongmi.android.tv.bean;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
public class Suggest {
@SerializedName("data")
private List<Data> data;
private static Suggest objectFrom(String str) {
return new Gson().fromJson(str, Suggest.class);
}
public static List<String> get(String str) {
List<String> items = new ArrayList<>();
for (Data item : objectFrom(str).getData()) items.add(item.getName());
return items;
}
private List<Data> getData() {
return data;
}
static class Data {
@SerializedName("name")
private String name;
private String getName() {
return name;
}
}
}

@ -21,6 +21,6 @@ public abstract class Callback implements okhttp3.Callback {
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) {
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
}
}

Loading…
Cancel
Save