cn.leancloud.search.SearchActivity Maven / Gradle / Ivy
package cn.leancloud.search;
import androidx.appcompat.app.AppCompatActivity;
import cn.leancloud.AVException;
import cn.leancloud.AVLogger;
import cn.leancloud.AVObject;
import cn.leancloud.callback.FindCallback;
import cn.leancloud.convertor.ObserverBuilder;
import cn.leancloud.utils.LogUtil;
import cn.leancloud.utils.StringUtil;
import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.alibaba.fastjson.JSON;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class SearchActivity extends AppCompatActivity {
private static AVLogger LOGGER = LogUtil.getLogger(SearchActivity.class);
ListView listView;
LinkedList searchResults = new LinkedList();
SearchResultAdapter adapter;
AVSearchQuery searchQuery;
static final int HIGHLIGHTS_MAX_LENGTH = 200;
FindCallback searchCallback;
View loadingView;
View emtpyResult;
public static String highlightFontStyle = null;
public void setSearchQuery(AVSearchQuery query) {
this.searchQuery = query;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(Resources.layout.search_activity(this));
setupActionBar();
listView = (ListView) findViewById(Resources.id.search_result_listview(this));
loadingView =
LayoutInflater.from(this).inflate(Resources.layout.search_loading(this), null);
emtpyResult = findViewById(Resources.id.search_emtpy_result(this));
listView.addFooterView(loadingView);
loadingView.setVisibility(View.INVISIBLE);
if (this.getIntent().getExtras() != null) {
String searchString =
getIntent().getExtras().getString(AVSearchQuery.DATA_EXTRA_SEARCH_KEY);
searchQuery = JSON.parseObject(searchString, AVSearchQuery.class);
}
if (null != searchQuery) {
searchCallback = new FindCallback() {
@Override
public void done(List avObjects, AVException avException) {
if (avException == null) {
searchResults.addAll(avObjects);
if (adapter == null) {
adapter = new SearchResultAdapter();
listView.setAdapter(adapter);
listView.setOnScrollListener(adapter);
} else {
adapter.notifyDataSetChanged();
hideLoadingView();
}
if (searchResults.size() == 0) {
emtpyResult.setVisibility(View.VISIBLE);
listView.setVisibility(View.GONE);
} else {
emtpyResult.setVisibility(View.GONE);
listView.setVisibility(View.VISIBLE);
}
}
}
};
searchQuery.findInBackground().subscribe(ObserverBuilder.buildSingleObserver(searchCallback));
}
}
@SuppressLint("NewApi")
private void setupActionBar() {
ActionBar actionBar = getActionBar();
if (actionBar != null) {
actionBar.setCustomView(Resources.layout.search_actionbar(this));
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setDisplayShowTitleEnabled(false);
View backButton =
actionBar.getCustomView()
.findViewById(Resources.id.search_actionbar_back(this));
backButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
finish();
}
});
}
}
public void showLoadingView() {
if (loadingView != null) {
loadingView.setVisibility(View.VISIBLE);
}
}
public void hideLoadingView() {
if (loadingView != null) {
loadingView.setVisibility(View.INVISIBLE);
}
}
public static String highlightStringMerge(Map> highlights) {
if (highlights != null) {
StringBuilder sb = new StringBuilder();
for (String key : highlights.keySet()) {
sb.append(StringUtil.join("...", highlights.get(key)));
}
if (sb.length() > HIGHLIGHTS_MAX_LENGTH) {
String tempString = sb.substring(0, HIGHLIGHTS_MAX_LENGTH);
StringBuilder tempSB = new StringBuilder(tempString).reverse();
int lastHeadTagIndex = tempSB.indexOf("");
int lastTailTagIndex = tempSB.indexOf(" ");
if (lastHeadTagIndex < lastTailTagIndex) {
return highLightStringStyle(tempSB.reverse().substring(0,
HIGHLIGHTS_MAX_LENGTH - lastTailTagIndex));
}
return highLightStringStyle(tempString);
}
return highLightStringStyle(sb.toString());
} else {
return "";
}
}
public static String highLightStringStyle(String string) {
string =
string.replaceAll("", StringUtil.isEmpty(highlightFontStyle)
? ""
: highlightFontStyle);
string = string.replaceAll("", "");
return string;
}
/**
* 您可以通过设定类似html font style来设定匹配高亮的风格
*
* example:
*
* @param style
*/
public static void setHighLightStyle(String style) {
highlightFontStyle = style;
}
public class ViewHolder {
TextView title;
TextView description;
TextView openApp;
}
public class SearchResultAdapter extends BaseAdapter implements AbsListView.OnScrollListener {
Context mContext = SearchActivity.this;
int lastVisibleItemId;
volatile boolean loading;
@Override
public int getCount() {
return searchResults.size();
}
@Override
public Object getItem(int position) {
return searchResults.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final AVObject item = (AVObject) getItem(position);
ViewHolder holder = null;
if (convertView == null) {
convertView =
LayoutInflater.from(SearchActivity.this).inflate(
Resources.layout.search_result_item(mContext), null);
holder = new ViewHolder();
holder.title =
(TextView) convertView.findViewById(Resources.id
.search_result_title(mContext));
holder.description =
(TextView) convertView.findViewById(Resources.id
.search_result_description(mContext));
holder.openApp =
(TextView) convertView.findViewById(Resources.id
.search_result_open_app(mContext));
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (!StringUtil.isEmpty(searchQuery.getTitleAttribute())) {
holder.title.setText(Html.fromHtml(item.get(searchQuery.getTitleAttribute()).toString()));
holder.description.setVisibility(View.VISIBLE);
holder.description.setText(Html
.fromHtml(highlightStringMerge((Map>) item
.get(AVSearchQuery.AVSEARCH_HIGHTLIGHT))));
} else {
holder.title.setText(Html.fromHtml(highlightStringMerge((Map>) item
.get(AVSearchQuery.AVSEARCH_HIGHTLIGHT))));
holder.description.setVisibility(View.GONE);
}
if (!StringUtil.isEmpty(item.getString(AVSearchQuery.AVSEARCH_APP_URL))) {
holder.openApp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_VIEW);
String link =
StringUtil.isEmpty(item.getString(AVSearchQuery.AVSEARCH_DEEP_LINK)) ? item
.getString(AVSearchQuery.AVSEARCH_APP_URL) : item
.getString(AVSearchQuery.AVSEARCH_DEEP_LINK);
i.setData(Uri.parse(link));
startActivity(i);
}
});
}
return convertView;
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
lastVisibleItemId = firstVisibleItem + visibleItemCount;
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (lastVisibleItemId >= searchResults.size()
&& scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
showLoadingView();
if (null != searchQuery) {
searchQuery.findInBackground().subscribe(ObserverBuilder.buildSingleObserver(searchCallback));
}
} else {
hideLoadingView();
}
}
}
}