增加搜索功能
This commit is contained in:
parent
bd31ac8780
commit
f341f3efe6
@ -0,0 +1,46 @@
|
||||
package com.hi.music.player.adapter;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.hi.music.player.databinding.ItemSuggestionBinding;
|
||||
|
||||
public class AdapterSuggestion extends BaseAdapter<String, ItemSuggestionBinding> {
|
||||
|
||||
@Override
|
||||
protected ItemSuggestionBinding getViewBinding(ViewGroup parent) {
|
||||
return ItemSuggestionBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||
VHolder<ItemSuggestionBinding> itemHolder = (VHolder<ItemSuggestionBinding>) holder;
|
||||
ItemSuggestionBinding vb = itemHolder.getVb();
|
||||
String text = data.get(position);
|
||||
vb.tvSuggestion.setText(text);
|
||||
vb.relayout.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(homeItemClickListener!= null){
|
||||
homeItemClickListener.onClickItemSuggestion(true,text);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
vb.imFillIn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(homeItemClickListener!= null){
|
||||
homeItemClickListener.onClickItemSuggestion(false,text);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -23,4 +23,15 @@ public interface HomeItemClickListener {
|
||||
default void onClickItemCategoryList(ResponsePlayListInfo data,int musicIndex) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 点击了搜索建议
|
||||
* @param isSearch true 直接搜索 false 输入搜索建议文字
|
||||
* @param data
|
||||
*/
|
||||
default void onClickItemSuggestion(boolean isSearch,String data) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
package com.hi.music.player.javabean.requestbody;
|
||||
|
||||
import com.hi.music.player.javabean.requestbody.child.Client;
|
||||
import com.hi.music.player.javabean.requestbody.child.ContextBody;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* 搜索建议接口
|
||||
*/
|
||||
public class BodySearch implements Serializable {
|
||||
|
||||
private String query = "";
|
||||
private ContextBody context = new ContextBody();
|
||||
|
||||
public String getQuery() {
|
||||
return query;
|
||||
}
|
||||
|
||||
public void setQuery(String query) {
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public ContextBody getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public void setContext(ContextBody context) {
|
||||
this.context = context;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.hi.music.player.javabean.requestbody;
|
||||
|
||||
import com.hi.music.player.javabean.requestbody.child.Client;
|
||||
import com.hi.music.player.javabean.requestbody.child.ContextBody;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* 搜索建议接口
|
||||
*/
|
||||
public class BodySearchSuggestion implements Serializable {
|
||||
|
||||
private String input = "";
|
||||
|
||||
|
||||
public String getInput() {
|
||||
return input;
|
||||
}
|
||||
|
||||
public void setInput(String input) {
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
private ContextBody context = new ContextBody();
|
||||
|
||||
public ContextBody getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public void setContext(ContextBody context) {
|
||||
this.context = context;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package com.hi.music.player.javabean.requestbody.child;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
public class Client implements Serializable {
|
||||
private String clientName = "WEB_REMIX";
|
||||
//1.20240506.01.00
|
||||
private String clientVersion = "1.20220918";
|
||||
private String hl = Locale.getDefault().getLanguage();
|
||||
private String gl = "US";
|
||||
private String platform = "DESKTOP";
|
||||
|
||||
private String visitorData;
|
||||
|
||||
public String getVisitorData() {
|
||||
return visitorData;
|
||||
}
|
||||
|
||||
public void setVisitorData(String visitorData) {
|
||||
this.visitorData = visitorData;
|
||||
}
|
||||
|
||||
|
||||
public void setClientName(String clientName) {
|
||||
this.clientName = clientName;
|
||||
}
|
||||
|
||||
public void setClientVersion(String clientVersion) {
|
||||
this.clientVersion = clientVersion;
|
||||
}
|
||||
|
||||
public void setPlatform(String platform) {
|
||||
this.platform = platform;
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,37 +23,7 @@ public class ContextBody {
|
||||
}
|
||||
|
||||
|
||||
public static class Client implements Serializable {
|
||||
private String clientName = "WEB_REMIX";
|
||||
//1.20240506.01.00
|
||||
private String clientVersion = "1.20220918";
|
||||
private String hl = Locale.getDefault().getLanguage();
|
||||
private String gl = "US";
|
||||
private String platform = "DESKTOP";
|
||||
|
||||
private String visitorData;
|
||||
|
||||
public String getVisitorData() {
|
||||
return visitorData;
|
||||
}
|
||||
|
||||
public void setVisitorData(String visitorData) {
|
||||
this.visitorData = visitorData;
|
||||
}
|
||||
|
||||
|
||||
public void setClientName(String clientName) {
|
||||
this.clientName = clientName;
|
||||
}
|
||||
|
||||
public void setClientVersion(String clientVersion) {
|
||||
this.clientVersion = clientVersion;
|
||||
}
|
||||
|
||||
public void setPlatform(String platform) {
|
||||
this.platform = platform;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ThirdParty{
|
||||
//https://www.youtube.com/watch?v=UqyT8IEBkvY
|
||||
|
||||
@ -323,6 +323,84 @@ public class JsonHelper {
|
||||
}
|
||||
|
||||
|
||||
public static List<String> ResolveSearchSuggestion(JSONObject jsonObject) {
|
||||
try {
|
||||
List<String> stringList = new ArrayList<>();
|
||||
JSONArray contents = jsonObject.getJSONArray("contents");
|
||||
for (int i = 0; i < contents.length(); i++) {
|
||||
JSONArray jsonArray = contents.getJSONObject(i)
|
||||
.getJSONObject("searchSuggestionsSectionRenderer")
|
||||
.getJSONArray("contents");
|
||||
|
||||
for (int j = 0; j < jsonArray.length(); j++) {
|
||||
|
||||
JSONObject searchSuggestionRenderer = jsonArray.getJSONObject(j)
|
||||
.optJSONObject("searchSuggestionRenderer");
|
||||
if (searchSuggestionRenderer != null) {
|
||||
String string = searchSuggestionRenderer
|
||||
.getJSONObject("navigationEndpoint")
|
||||
.getJSONObject("searchEndpoint")
|
||||
.getString("query");
|
||||
stringList.add(string);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return stringList;
|
||||
|
||||
} catch (JSONException e) {
|
||||
CommonUtils.LogErrorMsg("--" + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 解析搜索结果
|
||||
*
|
||||
* @param jsonObject
|
||||
*/
|
||||
public static void ResolveSearchResult(JSONObject jsonObject) {
|
||||
try {
|
||||
JSONArray jsonArray = jsonObject.getJSONObject("contents")
|
||||
.getJSONObject("tabbedSearchResultsRenderer")
|
||||
.getJSONArray("tabs")
|
||||
.getJSONObject(0)
|
||||
.getJSONObject("tabRenderer")
|
||||
.getJSONObject("content")
|
||||
.getJSONObject("sectionListRenderer")
|
||||
.getJSONArray("contents");
|
||||
for(int i =0;i<jsonArray.length();i++){
|
||||
if(i ==0){
|
||||
//最佳结果
|
||||
|
||||
}else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} catch (JSONException e) {
|
||||
CommonUtils.LogErrorMsg("--" + e.getMessage());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private static ResponsePlayListInfo getCommonCategoryList(JSONObject musicResponsiveListItemRenderer) throws JSONException {
|
||||
JSONObject jsonText = musicResponsiveListItemRenderer.getJSONArray("fixedColumns")
|
||||
.getJSONObject(0)
|
||||
@ -603,12 +681,12 @@ public class JsonHelper {
|
||||
int index = 0;
|
||||
if (maxBig) {
|
||||
index = length - 1;
|
||||
}else if(length>2){
|
||||
} else if (length > 2) {
|
||||
index = length - 2;
|
||||
}
|
||||
String pngUrl = jsonArray.getJSONObject(index).getString("url");
|
||||
|
||||
CommonUtils.LogMsg("----------取封面index="+index);
|
||||
CommonUtils.LogMsg("----------取封面index=" + index);
|
||||
|
||||
return pngUrl;
|
||||
} catch (JSONException exception) {
|
||||
|
||||
@ -51,7 +51,24 @@ public interface MusicApi {
|
||||
|
||||
//首页分类项下的播放列表子页面 (类型1:单曲合集、2:专辑、3:音乐视频合集 ,不同类型返回数据结构有区别)
|
||||
@POST("youtubei/v1/browse?prettyPrint=false")
|
||||
@Headers("X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8")
|
||||
@Headers({"X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8"})
|
||||
Observable<ResponseBody> getCategoryList(@Body RequestBody requestBody);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@POST("youtubei/v1/music/get_search_suggestions?prettyPrint=false")
|
||||
@Headers({"X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8",
|
||||
"X-Goog-FieldMask:contents.searchSuggestionsSectionRenderer.contents.searchSuggestionRenderer.navigationEndpoint.searchEndpoint.query"})
|
||||
Observable<ResponseBody> getSearchSuggestion(@Body RequestBody requestBody);
|
||||
|
||||
|
||||
|
||||
|
||||
// "X-Goog-FieldMask:contents.tabbedSearchResultsRenderer.tabs.tabRenderer.content.sectionListRenderer.contents.musicShelfRenderer(continuations,contents.musicResponsiveListItemRenderer(flexColumns,fixedColumns,thumbnail,navigationEndpoint))"
|
||||
@POST("youtubei/v1/search?prettyPrint=false")
|
||||
@Headers({"X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8"})
|
||||
Observable<ResponseBody> getSearch(@Body RequestBody requestBody);
|
||||
|
||||
}
|
||||
|
||||
@ -5,6 +5,9 @@ import com.hi.music.player.api.RequestListener;
|
||||
import com.hi.music.player.javabean.requestbody.BodyHome;
|
||||
import com.hi.music.player.javabean.requestbody.BodyPlay;
|
||||
import com.hi.music.player.javabean.requestbody.BodyPlayUrl;
|
||||
import com.hi.music.player.javabean.requestbody.BodySearch;
|
||||
import com.hi.music.player.javabean.requestbody.BodySearchSuggestion;
|
||||
import com.hi.music.player.javabean.requestbody.child.Client;
|
||||
import com.hi.music.player.javabean.requestbody.child.ContextBody;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -32,8 +35,8 @@ public class RetrofitManager {
|
||||
public MediaType JSON = MediaType.get("application/json; charset=utf-8");
|
||||
private MusicApi musicApi;
|
||||
|
||||
private String header1="playlistPanelVideoRenderer(title,navigationEndpoint,longBylineText,shortBylineText,thumbnail,lengthText)";
|
||||
private String header ="contents.singleColumnMusicWatchNextResultsRenderer.tabbedRenderer.watchNextTabbedResultsRenderer.tabs.tabRenderer.content.musicQueueRenderer.content.playlistPanelRenderer(continuations,contents(automixPreviewVideoRenderer,"+header1+"))";
|
||||
private String header1 = "playlistPanelVideoRenderer(title,navigationEndpoint,longBylineText,shortBylineText,thumbnail,lengthText)";
|
||||
private String header = "contents.singleColumnMusicWatchNextResultsRenderer.tabbedRenderer.watchNextTabbedResultsRenderer.tabs.tabRenderer.content.musicQueueRenderer.content.playlistPanelRenderer(continuations,contents(automixPreviewVideoRenderer," + header1 + "))";
|
||||
|
||||
private RetrofitManager() {
|
||||
|
||||
@ -89,7 +92,7 @@ public class RetrofitManager {
|
||||
.subscribe(new ObserverWrapper<ResponseBody>(requestListener));
|
||||
}
|
||||
|
||||
public void getHomeMoreData(String continuation,String itct,String visitorData,RequestListener<ResponseBody> requestListener) {
|
||||
public void getHomeMoreData(String continuation, String itct, String visitorData, RequestListener<ResponseBody> requestListener) {
|
||||
BodyHome bodyHome = new BodyHome();
|
||||
bodyHome.getContext().getClient().setVisitorData(visitorData);
|
||||
Gson gson = new Gson();
|
||||
@ -97,12 +100,12 @@ public class RetrofitManager {
|
||||
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
|
||||
|
||||
HashMap<String, String> stringHashMap = new HashMap<>();
|
||||
stringHashMap.put("ctoken",continuation);
|
||||
stringHashMap.put("continuation",continuation);
|
||||
stringHashMap.put("type","next");
|
||||
stringHashMap.put("itct",itct);
|
||||
stringHashMap.put("prettyPrint","false");
|
||||
musicApi.getHomeMoreData(continuation,continuation,"next",itct,false,requestBody)
|
||||
stringHashMap.put("ctoken", continuation);
|
||||
stringHashMap.put("continuation", continuation);
|
||||
stringHashMap.put("type", "next");
|
||||
stringHashMap.put("itct", itct);
|
||||
stringHashMap.put("prettyPrint", "false");
|
||||
musicApi.getHomeMoreData(continuation, continuation, "next", itct, false, requestBody)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.unsubscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
@ -119,7 +122,7 @@ public class RetrofitManager {
|
||||
Gson gson = new Gson();
|
||||
String s = gson.toJson(bodyPlay);
|
||||
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
|
||||
musicApi.getMusicPlayPage(header,requestBody)
|
||||
musicApi.getMusicPlayPage(header, requestBody)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.unsubscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
@ -127,15 +130,14 @@ public class RetrofitManager {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void getPlayUrl(String videoId,RequestListener<ResponseBody> requestListener) {
|
||||
public void getPlayUrl(String videoId, RequestListener<ResponseBody> requestListener) {
|
||||
BodyPlayUrl bodyPlay = new BodyPlayUrl();
|
||||
bodyPlay.setVideoId(videoId);
|
||||
ContextBody.Client client = bodyPlay.getContext().getClient();
|
||||
Client client = bodyPlay.getContext().getClient();
|
||||
client.setClientName("ANDROID_MUSIC");
|
||||
client.setClientVersion("5.28.1");
|
||||
client.setPlatform("MOBILE");
|
||||
bodyPlay.getContext().getThirdParty().setEmbedUrl("https://www.youtube.com/watch?v="+videoId);
|
||||
bodyPlay.getContext().getThirdParty().setEmbedUrl("https://www.youtube.com/watch?v=" + videoId);
|
||||
|
||||
|
||||
Gson gson = new Gson();
|
||||
@ -149,13 +151,12 @@ public class RetrofitManager {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void getCategoryList(String browserId,RequestListener<ResponseBody> requestListener) {
|
||||
public void getCategoryList(String browserId, RequestListener<ResponseBody> requestListener) {
|
||||
BodyHome bodyHome = new BodyHome();
|
||||
bodyHome.setBrowseId(browserId);
|
||||
// bodyHome.setBrowseId("VLPLI-asvmHZWNo_xjMMfD_v2O2lTyCdrjaK");
|
||||
|
||||
ContextBody.Client client = bodyHome.getContext().getClient();
|
||||
Client client = bodyHome.getContext().getClient();
|
||||
client.setClientVersion("1.20240506.01.00");
|
||||
|
||||
|
||||
@ -164,13 +165,44 @@ public class RetrofitManager {
|
||||
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
|
||||
|
||||
|
||||
|
||||
musicApi.getCategoryList(requestBody)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.unsubscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new ObserverWrapper<ResponseBody>(requestListener));
|
||||
.subscribe(new ObserverWrapper<>(requestListener));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void getSearchSuggestion(String input, RequestListener<ResponseBody> requestListener) {
|
||||
BodySearchSuggestion body = new BodySearchSuggestion();
|
||||
body.setInput(input);
|
||||
Client client = body.getContext().getClient();
|
||||
client.setClientVersion("1.20240506.01.00");
|
||||
Gson gson = new Gson();
|
||||
String s = gson.toJson(body);
|
||||
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
|
||||
musicApi.getSearchSuggestion(requestBody)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.unsubscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new ObserverWrapper<>(requestListener));
|
||||
}
|
||||
|
||||
|
||||
public void getSearch(String query, RequestListener<ResponseBody> requestListener) {
|
||||
BodySearch body = new BodySearch();
|
||||
body.setQuery(query);
|
||||
Client client = body.getContext().getClient();
|
||||
client.setClientVersion("1.20240506.01.00");
|
||||
Gson gson = new Gson();
|
||||
String s = gson.toJson(body);
|
||||
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
|
||||
musicApi.getSearch(requestBody)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.unsubscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new ObserverWrapper<>(requestListener));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,29 @@
|
||||
package com.hi.music.player.ui.fragmnt;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import com.hi.music.player.adapter.AdapterSuggestion;
|
||||
import com.hi.music.player.api.HomeItemClickListener;
|
||||
import com.hi.music.player.databinding.FragmentSearchBinding;
|
||||
import com.hi.music.player.helper.CommonUtils;
|
||||
import com.hi.music.player.ui.fragmnt.viewmodel.VMSearch;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class SearchFragment extends BaseFragment<FragmentSearchBinding> {
|
||||
public class SearchFragment extends BaseFragment<FragmentSearchBinding> implements HomeItemClickListener, View.OnClickListener {
|
||||
|
||||
|
||||
private VMSearch vmSearch;
|
||||
|
||||
@Override
|
||||
protected FragmentSearchBinding getFragmentVb() {
|
||||
return FragmentSearchBinding.inflate(getLayoutInflater());
|
||||
@ -13,6 +31,82 @@ public class SearchFragment extends BaseFragment<FragmentSearchBinding> {
|
||||
|
||||
@Override
|
||||
protected void initView() {
|
||||
// Vb.etSearch.requestFocus();
|
||||
vmSearch = getFragmentScopeViewModel(VMSearch.class);
|
||||
|
||||
Vb.etSearch.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
String input = s.toString();
|
||||
if (!input.isEmpty()) {
|
||||
vmSearch.getSuggestion(input);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
Vb.etSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
|
||||
String s = v.getText().toString();
|
||||
CommonUtils.LogMsg("------------v=" + s);
|
||||
startQuery(s);
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
});
|
||||
initSuggestionRecycler();
|
||||
}
|
||||
|
||||
private void initSuggestionRecycler() {
|
||||
AdapterSuggestion adapterSuggestion = new AdapterSuggestion();
|
||||
Vb.recyclerSuggestion.setLayoutManager(new LinearLayoutManager(requireContext()));
|
||||
Vb.recyclerSuggestion.setAdapter(adapterSuggestion);
|
||||
adapterSuggestion.setHomeItemClickListener(this);
|
||||
Vb.imCancel.setOnClickListener(this);
|
||||
vmSearch.suggestion.observe(getViewLifecycleOwner(), new Observer<List<String>>() {
|
||||
@Override
|
||||
public void onChanged(List<String> strings) {
|
||||
if (strings != null) {
|
||||
adapterSuggestion.setData(strings);
|
||||
CommonUtils.LogMsg("------------更新=");
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void startQuery(String query){
|
||||
Vb.recyclerSuggestion.setVisibility(View.GONE);
|
||||
Vb.recyclerResult.setVisibility(View.VISIBLE);
|
||||
vmSearch.getSearchResult(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickItemSuggestion(boolean isSearch, String data) {
|
||||
if (isSearch) {
|
||||
startQuery(data);
|
||||
} else {
|
||||
Vb.etSearch.setText(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v.equals(Vb.imCancel)) {
|
||||
Vb.etSearch.setText("");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
package com.hi.music.player.ui.fragmnt.viewmodel;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import com.hi.music.player.api.RequestListener;
|
||||
import com.hi.music.player.helper.CommonUtils;
|
||||
import com.hi.music.player.javabean.response.ResponseHome;
|
||||
import com.hi.music.player.network.JsonHelper;
|
||||
import com.hi.music.player.network.RetrofitManager;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import okhttp3.ResponseBody;
|
||||
|
||||
public class VMSearch extends ViewModel {
|
||||
private MutableLiveData<List<String>> _suggestion = new MutableLiveData<List<String>>();
|
||||
public LiveData<List<String>> suggestion = _suggestion;
|
||||
public void getSuggestion(String input) {
|
||||
RetrofitManager.getInstance().getSearchSuggestion(input,new RequestListener<ResponseBody>() {
|
||||
|
||||
@Override
|
||||
public void onFail(String errorMsg) {
|
||||
_suggestion.setValue(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(JSONObject data) {
|
||||
if (data != null) {
|
||||
List<String> stringList = JsonHelper.ResolveSearchSuggestion(data);
|
||||
CommonUtils.LogMsg("------------onSuccess= stringList="+stringList );
|
||||
_suggestion.setValue(stringList);
|
||||
} else {
|
||||
_suggestion.setValue(null);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void getSearchResult(String query) {
|
||||
RetrofitManager.getInstance().getSearch(query, new RequestListener<ResponseBody>() {
|
||||
|
||||
@Override
|
||||
public void onFail(String errorMsg) {
|
||||
// _data.setValue(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(JSONObject data) {
|
||||
if (data != null) {
|
||||
JsonHelper.ResolveSearchResult(data);
|
||||
// _data.setValue(responseHome);
|
||||
} else {
|
||||
// _data.setValue(null);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
7
app/src/main/res/drawable/bg_search.xml
Normal file
7
app/src/main/res/drawable/bg_search.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="20dp"/>
|
||||
<solid android:color="@color/black"/>
|
||||
|
||||
</shape>
|
||||
20
app/src/main/res/drawable/icon_cancel.xml
Normal file
20
app/src/main/res/drawable/icon_cancel.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M7,7L17,17"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="1.5"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#ffffff"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M7,17L17,7"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="1.5"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#ffffff"
|
||||
android:strokeLineCap="round"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/icon_fill_in.xml
Normal file
9
app/src/main/res/drawable/icon_fill_in.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="@color/white"
|
||||
android:pathData="M820.3,782.6L288.5,250.9h444.4c14.6,0 26.4,-11.8 26.4,-26.4s-11.8,-26.4 -26.4,-26.4H233.1c-19.4,0 -35.1,15.7 -35.1,35.1v499.8c0,14.6 11.8,26.4 26.4,26.4s26.4,-11.8 26.4,-26.4V287.7l532.2,532.2c5.1,5.1 11.9,7.7 18.6,7.7s13.5,-2.6 18.6,-7.7c10.4,-10.3 10.4,-27 0.2,-37.3z"/>
|
||||
</vector>
|
||||
10
app/src/main/res/drawable/icon_search.xml
Normal file
10
app/src/main/res/drawable/icon_search.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M11.12,20.72C5.84,20.72 1.52,16.4 1.52,11.12C1.52,5.84 5.84,1.52 11.12,1.52C16.399,1.52 20.719,5.84 20.719,11.12C20.719,16.4 16.399,20.72 11.12,20.72ZM11.12,19.12C15.519,19.12 19.119,15.52 19.119,11.12C19.119,6.72 15.519,3.12 11.12,3.12C6.72,3.12 3.12,6.72 3.12,11.12C3.12,15.52 6.72,19.12 11.12,19.12ZM17.039,20.4C16.719,20.08 16.799,19.52 17.119,19.28C17.44,19.04 18,19.04 18.24,19.36L19.76,21.2C20.08,21.52 20,22.08 19.68,22.32C19.36,22.56 18.799,22.56 18.559,22.24L17.039,20.4Z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillAlpha="0.85"/>
|
||||
</vector>
|
||||
@ -1,14 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/default_play_list_color"
|
||||
tools:context=".ui.fragmnt.SearchFragment">
|
||||
|
||||
<!-- TODO: Update blank fragment layout -->
|
||||
<TextView
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/hello_blank_fragment" />
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginStart="22dp"
|
||||
android:layout_marginEnd="22dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:id="@+id/layout_et"
|
||||
android:background="@drawable/bg_search" >
|
||||
|
||||
</FrameLayout>
|
||||
<EditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@null"
|
||||
android:layout_toStartOf="@id/im_cancel"
|
||||
android:textColorHint="@color/seek_bg_color"
|
||||
android:paddingStart="20dp"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:id="@+id/et_search"
|
||||
android:textColor="@color/white"
|
||||
android:maxLines="1"
|
||||
android:inputType="text"
|
||||
android:imeOptions="actionSearch"
|
||||
android:hint="@string/search_hint"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/im_cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:paddingStart="13dp"
|
||||
android:paddingEnd="13dp"
|
||||
android:src="@drawable/icon_cancel"/>
|
||||
</RelativeLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/layout_et"
|
||||
android:layout_alignStart="@id/layout_et"
|
||||
android:layout_alignEnd="@id/layout_et"
|
||||
android:id="@+id/recycler_suggestion"/>
|
||||
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/layout_et"
|
||||
android:layout_alignStart="@id/layout_et"
|
||||
android:layout_alignEnd="@id/layout_et"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/recycler_result"/>
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
41
app/src/main/res/layout/item_suggestion.xml
Normal file
41
app/src/main/res/layout/item_suggestion.xml
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/relayout"
|
||||
android:layout_height="50dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:id="@+id/im"
|
||||
android:src="@drawable/icon_search" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/white"
|
||||
android:layout_toEndOf="@id/im"
|
||||
android:layout_marginStart="25dp"
|
||||
android:text="@string/app_name"
|
||||
android:maxLines="1"
|
||||
android:id="@+id/tv_suggestion"
|
||||
android:ellipsize="end"
|
||||
android:layout_toStartOf="@id/im_fill_in"
|
||||
android:layout_centerVertical="true"
|
||||
android:textSize="16sp" />
|
||||
|
||||
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:id="@+id/im_fill_in"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerInParent="true"
|
||||
android:src="@drawable/icon_fill_in" />
|
||||
|
||||
</RelativeLayout>
|
||||
@ -24,4 +24,5 @@
|
||||
<string name="play_next">Play next</string>
|
||||
<string name="retry">Try again</string>
|
||||
<string name="An_error_occurred">An error occurred</string>
|
||||
<string name="search_hint">Search songs, artists…</string>
|
||||
</resources>
|
||||
Loading…
Reference in New Issue
Block a user