package net.coding.program.maopao;
import android.content.Intent;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.SearchView;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.baidu.mapapi.model.LatLng;
import net.coding.program.FootUpdate;
import net.coding.program.R;
import net.coding.program.common.Global;
import net.coding.program.common.ui.BackActivity;
import net.coding.program.maopao.item.LocationItem;
import net.coding.program.model.LocationObject;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.Extra;
import org.androidannotations.annotations.ItemClick;
import org.androidannotations.annotations.OnActivityResult;
import org.androidannotations.annotations.OptionsMenu;
import org.androidannotations.annotations.ViewById;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Neutra on 2015/3/11.
*/
@EActivity(R.layout.activity_choose_location)
@OptionsMenu(R.menu.location_search)
public class LocationSearchActivity extends BackActivity implements FootUpdate.LoadMore {
// 行政区划,房地产,公司企业,美食,休闲娱乐,宾馆,购物,旅游景点,生活服务,汽车服务,结婚,丽人,金融,运动健身,医疗,教育,培训机构,交通设施,自然地物,政府机构,门址,道路
private static final String RECOMMEND_KEYS = "美食$休闲娱乐$公司企业$旅游景点$道路$宾馆$生活服务$医疗";
static public int sSearchPos = 0;
@ViewById
ListView listView;
@Extra
LocationObject selectedLocation;
private ChooseAdapter chooseAdapter;
private SearchAdapter searchAdapter;
private LocationProvider locationProvider;
private String currentCity = null;
private String currentArea = null;
private double latitude, longitude;
private boolean isLoadingLocation = false;
private SearchView searchView;
private LocationObject emptyLocation = LocationObject.undefined();
public static int getSearchPos() {
return sSearchPos;
}
@AfterViews
protected final void initLocationSearchActivity() {
mFootUpdate.init(listView, mInflater, this);
chooseAdapter = new ChooseAdapter();
searchAdapter = new SearchAdapter();
listView.setAdapter(chooseAdapter);
reset();
loadMore();
}
@Override
public void loadMore() {
mFootUpdate.showLoading();
if (listView.getAdapter() == searchAdapter) {
searchAdapter.loadMore();
} else {
chooseAdapter.loadMore();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (chooseAdapter != null && chooseAdapter.searcher != null) {
chooseAdapter.searcher.destory();
}
if (searchAdapter != null && searchAdapter.searcher != null) {
searchAdapter.searcher.destory();
}
}
private void reset() {
currentCity = null;
latitude = longitude = 0;
chooseAdapter.searcher.configure(this, null, null);
chooseAdapter.list.clear();
chooseAdapter.list.add(emptyLocation);
if (selectedLocation != null && selectedLocation.type != LocationObject.Type.Undefined) {
chooseAdapter.list.add(selectedLocation);
} else {
selectedLocation = emptyLocation;
}
chooseAdapter.notifyDataSetChanged();
searchAdapter.disabled();
}
private void reloadLocation() {
if (isLoadingLocation) return;
isLoadingLocation = true;
if (locationProvider == null) {
locationProvider = new LocationProvider(this);
}
locationProvider.requestLocation(new LocationProvider.LocationResultListener() {
@Override
public void onLocationResult(boolean success, String city, String area, double latitude, double longitude) {
isLoadingLocation = false;
if (LocationSearchActivity.this.isFinishing()) return;
if (success) {
currentCity = city;
currentArea = area;
LocationSearchActivity.this.latitude = latitude;
LocationSearchActivity.this.longitude = longitude;
if (!(selectedLocation != null && selectedLocation.type == LocationObject.Type.City && selectedLocation.name.equals(currentCity))) {
chooseAdapter.list.add(1, LocationObject.city(currentCity, latitude, longitude));
chooseAdapter.notifyDataSetChanged();
}
LatLng latLng = new LatLng(latitude, longitude);
chooseAdapter.searcher.configure(LocationSearchActivity.this, latLng, chooseAdapter);
searchAdapter.searcher.configure(LocationSearchActivity.this, latLng, searchAdapter);
LocationSearchActivity.this.supportInvalidateOptionsMenu();
loadMore();
} else {
currentCity = null;
mFootUpdate.showFail();
}
}
});
}
@ItemClick(R.id.listView)
void onItemClick(final LocationObject data) {
if (data == null) return;
if (data.type == LocationObject.Type.newCustom) {
LocationEditActivity_.intent(this)
.name(data.name).city(currentCity).area(currentArea)
.latitude(latitude).longitude(longitude)
.startForResult(MaopaoAddActivity.RESULT_REQUEST_LOCATION);
return;
}
data.city = currentCity;
Intent intent = new Intent();
intent.putExtra("location", data);
setResult(RESULT_OK, intent);
finish();
}
@OnActivityResult(MaopaoAddActivity.RESULT_REQUEST_LOCATION)
void on_RESULT_REQUEST_LOCATION(int result, Intent intent, @OnActivityResult.Extra LocationObject location) {
if (result == RESULT_OK) {
setResult(RESULT_OK, intent);
finish();
}
}
private void initActionView(MenuItem searchItem) {
if (searchView != null) return;
searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
try { // 更改搜索按钮的icon
int searchImgId = getResources().getIdentifier("android:id/search_button", null, null);
ImageView v = (ImageView) searchView.findViewById(searchImgId);
v.setImageResource(R.drawable.ic_menu_search);
} catch (Exception e) {
Global.errorLog(e);
}
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
return true;
}
@Override
public boolean onQueryTextChange(String s) {
++sSearchPos;
searchAdapter.reload(searchView.getQuery().toString());
return true;
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuItem menuItem = menu.findItem(R.id.action_search);
if (TextUtils.isEmpty(currentCity)) {
menuItem.setVisible(false);
} else {
menuItem.setVisible(true);
MenuItemCompat.setOnActionExpandListener(menuItem, new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
if (listView != null && searchAdapter != null) {
listView.setAdapter(searchAdapter);
searchAdapter.reload("");
initActionView(item);
searchView.requestFocus();
mFootUpdate.dismiss();
}
return true;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
if (listView != null && chooseAdapter != null) {
listView.setAdapter(chooseAdapter);
}
return true;
}
});
}
return super.onCreateOptionsMenu(menu);
}
private abstract class LocationAdapter extends BaseAdapter implements FootUpdate.LoadMore {
ArrayList<LocationObject> list = new ArrayList<>();
@Override
public int getCount() {
return list.size();
}
@Override
public LocationObject getItem(int position) {
return position >= 0 && position < list.size() ? list.get(position) : null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.location_list_item, listView, false);
}
LocationItem locationItem = LocationItem.from(convertView);
LocationObject data = getItem(position);
bindItem(locationItem, position, data);
return convertView;
}
protected abstract void bindItem(LocationItem locationItem, int position, LocationObject data);
}
private class ChooseAdapter extends LocationAdapter implements LocationSearcher.SearchResultListener {
LocationSearcherGroup searcher = new LocationSearcherGroup(RECOMMEND_KEYS);
@Override
public void bindItem(LocationItem locationItem, int position, LocationObject data) {
locationItem.bind(data, selectedLocation == data);
if (position == list.size() - 1) {
loadMore();
}
}
@Override
public void loadMore() {
if (TextUtils.isEmpty(currentCity)) {
reloadLocation();
} else {
searcher.search();
}
}
@Override
public void onSearchResult(List<LocationObject> locations) {
if (LocationSearchActivity.this.isFinishing()) return;
addToList(locations);
notifyDataSetChanged();
if (searcher.isComplete()) {
mFootUpdate.dismiss();
} else {
mFootUpdate.showLoading();
}
}
private void addToList(List<LocationObject> locations) {
if (locations == null) return;
if (selectedLocation != null) {
if (selectedLocation.type == LocationObject.Type.City) {
String distinceKey = selectedLocation.name;
if (distinceKey != null) {
for (LocationObject item : locations) {
if (!TextUtils.isEmpty(item.address) && !distinceKey.equals(item.name)) {
list.add(item);
}
}
return;
}
} else if (selectedLocation.type == LocationObject.Type.Normal) {
String distinceKeyName = selectedLocation.name;
String distinceKeyAddr = selectedLocation.address == null ? "" : selectedLocation.address;
if (distinceKeyName != null) {
for (LocationObject item : locations) {
if (!TextUtils.isEmpty(item.address) && !distinceKeyName.equals(item.name) && !distinceKeyAddr.equals(item.address)) {
list.add(item);
}
}
return;
}
}
}
list.addAll(locations);
}
}
private class SearchAdapter extends LocationAdapter implements LocationSearcher.SearchResultListener {
static final int STATE_DISABLED = 0;
static final int STATE_SEARCH = 1;
static final int STATE_COMPLETE = 2;
private LocationSearcherGroup searcher;
private int state = STATE_DISABLED;
private View footView;
private TextView customTextView;
SearchAdapter() {
searcher = new LocationSearcherGroup();
searcher.configure(LocationSearchActivity.this, new LatLng(latitude, longitude), this);
footView = getLayoutInflater().inflate(R.layout.location_list_custom, listView, false);
customTextView = (TextView) footView.findViewById(R.id.secondary);
}
void disabled() {
state = STATE_DISABLED;
list.clear();
mFootUpdate.dismiss();
}
void reload(String keyword) {
keyword = keyword == null ? "" : keyword.trim();
if (!keyword.equals(searcher.getKeyword())) {
state = STATE_SEARCH;
list.clear();
notifyDataSetChanged();
mFootUpdate.dismiss();
searcher.setKeyword(keyword);
if (searcher.isKeywordEmpty()) {
mFootUpdate.dismiss();
} else {
loadMore();
}
}
}
@Override
public void loadMore() {
if (state == STATE_SEARCH && !searcher.isKeywordEmpty()) {
mFootUpdate.showLoading();
searcher.search();
}
}
private void complete() {
if (state == STATE_SEARCH) {
state = STATE_COMPLETE;
mFootUpdate.dismiss();
String keyword = searcher.getKeyword();
if (!TextUtils.isEmpty(keyword)) {
boolean notFound = true;
for (LocationObject item : list) {
if (keyword.equals(item.name)) {
notFound = false;
break;
}
}
if (notFound) {
list.add(LocationObject.newCustom(keyword, latitude, longitude));
customTextView.setText("创建新的位置: " + keyword);
}
}
}
}
@Override
public void bindItem(LocationItem locationItem, int position, LocationObject data) {
locationItem.bind(data, false);
if (position == list.size() - 1) {
loadMore();
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (state == STATE_COMPLETE && position == list.size() - 1
&& getItem(position).type == LocationObject.Type.newCustom) {
return footView;
}
return super.getView(position, (footView == convertView ? null : convertView), parent);
}
@Override
public void onSearchResult(List<LocationObject> locations) {
if (locations != null) {
list.addAll(locations);
}
if (searcher.isComplete()) {
complete();
}
searchAdapter.notifyDataSetChanged();
}
}
}