android 完美仿京东地址选择DEMO
程序员文章站
2022-05-24 23:54:04
...
package chihane.jdaddressselector.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ListView;
public class UninterceptableListView extends ListView {
public UninterceptableListView(Context context) {
super(context);
}
public UninterceptableListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public UninterceptableListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
getParent().requestDisallowInterceptTouchEvent(true);
return super.onTouchEvent(ev);
}
}
展示数据的listviewimport java.util.List;
import chihane.jdaddressselector.model.City;
import chihane.jdaddressselector.model.County;
import chihane.jdaddressselector.model.Province;
import chihane.jdaddressselector.model.Street;
public interface AddressProvider {
void provideProvinces(AddressReceiver<Province> addressReceiver);
void provideCitiesWith(int provinceId, AddressReceiver<City> addressReceiver);
void provideCountiesWith(int cityId, AddressReceiver<County> addressReceiver);
void provideStreetsWith(int countyId, AddressReceiver<Street> addressReceiver);
interface AddressReceiver<T> {
void send(List<T> data);
}
}
数据提供接口package chihane.jdaddressselector;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.util.List;
import chihane.jdaddressselector.model.City;
import chihane.jdaddressselector.model.County;
import chihane.jdaddressselector.model.Province;
import chihane.jdaddressselector.model.Street;
import mlxy.utils.Lists;
public class AddressSelector implements AdapterView.OnItemClickListener {
private static final int INDEX_TAB_PROVINCE = 0;
private static final int INDEX_TAB_CITY = 1;
private static final int INDEX_TAB_COUNTY = 2;
private static final int INDEX_TAB_STREET = 3;
private static final int INDEX_INVALID = -1;
private static final int WHAT_PROVINCES_PROVIDED = 0;
private static final int WHAT_CITIES_PROVIDED = 1;
private static final int WHAT_COUNTIES_PROVIDED = 2;
private static final int WHAT_STREETS_PROVIDED = 3;
@SuppressWarnings("unchecked")
private Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case WHAT_PROVINCES_PROVIDED:
provinces = (List<Province>) msg.obj;
provinceAdapter.notifyDataSetChanged();
listView.setAdapter(provinceAdapter);
break;
case WHAT_CITIES_PROVIDED:
cities = (List<City>) msg.obj;
cityAdapter.notifyDataSetChanged();
if (Lists.notEmpty(cities)) {
// 以次级内容更新列表
listView.setAdapter(cityAdapter);
// 更新索引为次级
tabIndex = INDEX_TAB_CITY;
} else {
// 次级无内容,回调
callbackInternal();
}
break;
case WHAT_COUNTIES_PROVIDED:
counties = (List<County>) msg.obj;
countyAdapter.notifyDataSetChanged();
if (Lists.notEmpty(counties)) {
listView.setAdapter(countyAdapter);
tabIndex = INDEX_TAB_COUNTY;
} else {
callbackInternal();
}
break;
case WHAT_STREETS_PROVIDED:
streets = (List<Street>) msg.obj;
streetAdapter.notifyDataSetChanged();
if (Lists.notEmpty(streets)) {
listView.setAdapter(streetAdapter);
tabIndex = INDEX_TAB_STREET;
} else {
callbackInternal();
}
break;
}
updateTabsVisibility();
updateProgressVisibility();
updateIndicator();
return true;
}
});
private static AddressProvider DEFAULT_ADDRESS_PROVIDER;
private final Context context;
private OnAddressSelectedListener listener;
private AddressProvider addressProvider;
private View view;
private View indicator;
private TextView textViewProvince;
private TextView textViewCity;
private TextView textViewCounty;
private TextView textViewStreet;
private ProgressBar progressBar;
private ListView listView;
private ProvinceAdapter provinceAdapter;
private CityAdapter cityAdapter;
private CountyAdapter countyAdapter;
private StreetAdapter streetAdapter;
private List<Province> provinces;
private List<City> cities;
private List<County> counties;
private List<Street> streets;
private int provinceIndex = INDEX_INVALID;
private int cityIndex = INDEX_INVALID;
private int countyIndex = INDEX_INVALID;
private int streetIndex = INDEX_INVALID;
private int tabIndex = INDEX_TAB_PROVINCE;
public AddressSelector(Context context) {
this.context = context;
DEFAULT_ADDRESS_PROVIDER = new DefaultAddressProvider(context);
addressProvider = DEFAULT_ADDRESS_PROVIDER;
initViews();
initAdapters();
retrieveProvinces();
}
private void initAdapters() {
provinceAdapter = new ProvinceAdapter();
cityAdapter = new CityAdapter();
countyAdapter = new CountyAdapter();
streetAdapter = new StreetAdapter();
}
private void initViews() {
view = LayoutInflater.from(context).inflate(R.layout.address_selector, null);
this.progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
this.listView = (ListView) view.findViewById(R.id.listView);
this.indicator = view.findViewById(R.id.indicator);
this.textViewProvince = (TextView) view.findViewById(R.id.textViewProvince);
this.textViewCity = (TextView) view.findViewById(R.id.textViewCity);
this.textViewCounty = (TextView) view.findViewById(R.id.textViewCounty);
this.textViewStreet = (TextView) view.findViewById(R.id.textViewStreet);
this.textViewProvince.setOnClickListener(new OnProvinceTabClickListener());
this.textViewCity.setOnClickListener(new OnCityTabClickListener());
this.textViewCounty.setOnClickListener(new OnCountyTabClickListener());
this.textViewStreet.setOnClickListener(new OnStreetTabClickListener());
this.listView.setOnItemClickListener(this);
updateIndicator();
}
public View getView() {
return view;
}
private void updateIndicator() {
view.post(new Runnable() {
@Override
public void run() {
switch (tabIndex) {
case INDEX_TAB_PROVINCE:
buildIndicatorAnimatorTowards(textViewProvince).start();
break;
case INDEX_TAB_CITY:
buildIndicatorAnimatorTowards(textViewCity).start();
break;
case INDEX_TAB_COUNTY:
buildIndicatorAnimatorTowards(textViewCounty).start();
break;
case INDEX_TAB_STREET:
buildIndicatorAnimatorTowards(textViewStreet).start();
break;
}
}
});
}
private AnimatorSet buildIndicatorAnimatorTowards(TextView tab) {
ObjectAnimator xAnimator = ObjectAnimator.ofFloat(indicator, "X", indicator.getX(), tab.getX());
final ViewGroup.LayoutParams params = indicator.getLayoutParams();
ValueAnimator widthAnimator = ValueAnimator.ofInt(params.width, tab.getMeasuredWidth());
widthAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
params.width = (int) animation.getAnimatedValue();
indicator.setLayoutParams(params);
}
});
AnimatorSet set = new AnimatorSet();
set.setInterpolator(new FastOutSlowInInterpolator());
set.playTogether(xAnimator, widthAnimator);
return set;
}
private class OnProvinceTabClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
tabIndex = INDEX_TAB_PROVINCE;
listView.setAdapter(provinceAdapter);
if (provinceIndex != INDEX_INVALID) {
listView.setSelection(provinceIndex);
}
updateTabsVisibility();
updateIndicator();
}
}
private class OnCityTabClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
tabIndex = INDEX_TAB_CITY;
listView.setAdapter(cityAdapter);
if (cityIndex != INDEX_INVALID) {
listView.setSelection(cityIndex);
}
updateTabsVisibility();
updateIndicator();
}
}
private class OnCountyTabClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
tabIndex = INDEX_TAB_COUNTY;
listView.setAdapter(countyAdapter);
if (countyIndex != INDEX_INVALID) {
listView.setSelection(countyIndex);
}
updateTabsVisibility();
updateIndicator();
}
}
private class OnStreetTabClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
tabIndex = INDEX_TAB_STREET;
listView.setAdapter(streetAdapter);
if (streetIndex != INDEX_INVALID) {
listView.setSelection(streetIndex);
}
updateTabsVisibility();
updateIndicator();
}
}
private void updateTabsVisibility() {
textViewProvince.setVisibility(Lists.notEmpty(provinces) ? View.VISIBLE : View.GONE);
textViewCity.setVisibility(Lists.notEmpty(cities) ? View.VISIBLE : View.GONE);
textViewCounty.setVisibility(Lists.notEmpty(counties) ? View.VISIBLE : View.GONE);
textViewStreet.setVisibility(Lists.notEmpty(streets) ? View.VISIBLE : View.GONE);
textViewProvince.setEnabled(tabIndex != INDEX_TAB_PROVINCE);
textViewCity.setEnabled(tabIndex != INDEX_TAB_CITY);
textViewCounty.setEnabled(tabIndex != INDEX_TAB_COUNTY);
textViewStreet.setEnabled(tabIndex != INDEX_TAB_STREET);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch (tabIndex) {
case INDEX_TAB_PROVINCE:
Province province = provinceAdapter.getItem(position);
// 更新当前级别及子级标签文本
textViewProvince.setText(province.name);
textViewCity.setText("请选择");
textViewCounty.setText("请选择");
textViewStreet.setText("请选择");
// 清空子级数据
cities = null;
counties = null;
streets = null;
cityAdapter.notifyDataSetChanged();
countyAdapter.notifyDataSetChanged();
streetAdapter.notifyDataSetChanged();
// 更新已选中项
this.provinceIndex = position;
this.cityIndex = INDEX_INVALID;
this.countyIndex = INDEX_INVALID;
this.streetIndex = INDEX_INVALID;
// 更新选中效果
provinceAdapter.notifyDataSetChanged();
retrieveCitiesWith(province.id);
break;
case INDEX_TAB_CITY:
City city = cityAdapter.getItem(position);
textViewCity.setText(city.name);
textViewCounty.setText("请选择");
textViewStreet.setText("请选择");
counties = null;
streets = null;
countyAdapter.notifyDataSetChanged();
streetAdapter.notifyDataSetChanged();
this.cityIndex = position;
this.countyIndex = INDEX_INVALID;
this.streetIndex = INDEX_INVALID;
cityAdapter.notifyDataSetChanged();
retrieveCountiesWith(city.id);
break;
case INDEX_TAB_COUNTY:
County county = countyAdapter.getItem(position);
textViewCounty.setText(county.name);
textViewStreet.setText("请选择");
streets = null;
streetAdapter.notifyDataSetChanged();
this.countyIndex = position;
this.streetIndex = INDEX_INVALID;
countyAdapter.notifyDataSetChanged();
retrieveStreetsWith(county.id);
break;
case INDEX_TAB_STREET:
Street street = streetAdapter.getItem(position);
textViewStreet.setText(street.name);
this.streetIndex = position;
streetAdapter.notifyDataSetChanged();
callbackInternal();
break;
}
updateTabsVisibility();
updateIndicator();
}
private void callbackInternal() {
if (listener != null) {
Province province = provinces == null || provinceIndex == INDEX_INVALID ? null : provinces.get(provinceIndex);
City city = cities == null || cityIndex == INDEX_INVALID ? null : cities.get(cityIndex);
County county = counties == null || countyIndex == INDEX_INVALID ? null : counties.get(countyIndex);
Street street = streets == null || streetIndex == INDEX_INVALID ? null : streets.get(streetIndex);
listener.onAddressSelected(province, city, county, street);
}
}
private void updateProgressVisibility() {
ListAdapter adapter = listView.getAdapter();
int itemCount = adapter.getCount();
progressBar.setVisibility(itemCount > 0 ? View.GONE : View.VISIBLE);
}
private void retrieveProvinces() {
progressBar.setVisibility(View.VISIBLE);
addressProvider.provideProvinces(new AddressProvider.AddressReceiver<Province>() {
@Override
public void send(List<Province> data) {
handler.sendMessage(Message.obtain(handler, WHAT_PROVINCES_PROVIDED, data));
}
});
}
private void retrieveCitiesWith(int provinceId) {
progressBar.setVisibility(View.VISIBLE);
addressProvider.provideCitiesWith(provinceId, new AddressProvider.AddressReceiver<City>() {
@Override
public void send(List<City> data) {
handler.sendMessage(Message.obtain(handler, WHAT_CITIES_PROVIDED, data));
}
});
}
private void retrieveCountiesWith(int cityId) {
progressBar.setVisibility(View.VISIBLE);
addressProvider.provideCountiesWith(cityId, new AddressProvider.AddressReceiver<County>() {
@Override
public void send(List<County> data) {
handler.sendMessage(Message.obtain(handler, WHAT_COUNTIES_PROVIDED, data));
}
});
}
private void retrieveStreetsWith(int countyId) {
progressBar.setVisibility(View.VISIBLE);
addressProvider.provideStreetsWith(countyId, new AddressProvider.AddressReceiver<Street>() {
@Override
public void send(List<Street> data) {
handler.sendMessage(Message.obtain(handler, WHAT_STREETS_PROVIDED, data));
}
});
}
private class ProvinceAdapter extends BaseAdapter {
@Override
public int getCount() {
return provinces == null ? 0 : provinces.size();
}
@Override
public Province getItem(int position) {
return provinces.get(position);
}
@Override
public long getItemId(int position) {
return getItem(position).id;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_area, parent, false);
holder = new Holder();
holder.textView = (TextView) convertView.findViewById(R.id.textView);
holder.imageViewCheckMark = (ImageView) convertView.findViewById(R.id.imageViewCheckMark);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
Province item = getItem(position);
holder.textView.setText(item.name);
boolean checked = provinceIndex != INDEX_INVALID && provinces.get(provinceIndex).id == item.id;
holder.textView.setEnabled(!checked);
holder.imageViewCheckMark.setVisibility(checked ? View.VISIBLE : View.GONE);
return convertView;
}
class Holder {
TextView textView;
ImageView imageViewCheckMark;
}
}
private class CityAdapter extends BaseAdapter {
@Override
public int getCount() {
return cities == null ? 0 : cities.size();
}
@Override
public City getItem(int position) {
return cities.get(position);
}
@Override
public long getItemId(int position) {
return getItem(position).id;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_area, parent, false);
holder = new Holder();
holder.textView = (TextView) convertView.findViewById(R.id.textView);
holder.imageViewCheckMark = (ImageView) convertView.findViewById(R.id.imageViewCheckMark);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
City item = getItem(position);
holder.textView.setText(item.name);
boolean checked = cityIndex != INDEX_INVALID && cities.get(cityIndex).id == item.id;
holder.textView.setEnabled(!checked);
holder.imageViewCheckMark.setVisibility(checked ? View.VISIBLE : View.GONE);
return convertView;
}
class Holder {
TextView textView;
ImageView imageViewCheckMark;
}
}
private class CountyAdapter extends BaseAdapter {
@Override
public int getCount() {
return counties == null ? 0 : counties.size();
}
@Override
public County getItem(int position) {
return counties.get(position);
}
@Override
public long getItemId(int position) {
return getItem(position).id;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_area, parent, false);
holder = new Holder();
holder.textView = (TextView) convertView.findViewById(R.id.textView);
holder.imageViewCheckMark = (ImageView) convertView.findViewById(R.id.imageViewCheckMark);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
County item = getItem(position);
holder.textView.setText(item.name);
boolean checked = countyIndex != INDEX_INVALID && counties.get(countyIndex).id == item.id;
holder.textView.setEnabled(!checked);
holder.imageViewCheckMark.setVisibility(checked ? View.VISIBLE : View.GONE);
return convertView;
}
class Holder {
TextView textView;
ImageView imageViewCheckMark;
}
}
private class StreetAdapter extends BaseAdapter {
@Override
public int getCount() {
return streets == null ? 0 : streets.size();
}
@Override
public Street getItem(int position) {
return streets.get(position);
}
@Override
public long getItemId(int position) {
return getItem(position).id;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_area, parent, false);
holder = new Holder();
holder.textView = (TextView) convertView.findViewById(R.id.textView);
holder.imageViewCheckMark = (ImageView) convertView.findViewById(R.id.imageViewCheckMark);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
Street item = getItem(position);
holder.textView.setText(item.name);
boolean checked = streetIndex != INDEX_INVALID && streets.get(streetIndex).id == item.id;
holder.textView.setEnabled(!checked);
holder.imageViewCheckMark.setVisibility(checked ? View.VISIBLE : View.GONE);
return convertView;
}
class Holder {
TextView textView;
ImageView imageViewCheckMark;
}
}
public OnAddressSelectedListener getOnAddressSelectedListener() {
return listener;
}
public void setOnAddressSelectedListener(OnAddressSelectedListener listener) {
this.listener = listener;
}
public void setAddressProvider(AddressProvider addressProvider) {
this.addressProvider = addressProvider;
if (addressProvider == null) {
this.addressProvider = DEFAULT_ADDRESS_PROVIDER;
}
retrieveProvinces();
}
}
主要类,主要逻辑都在这里
package chihane.jdaddressselector;
import android.app.Dialog;
import android.content.Context;
import android.view.Gravity;
import android.view.Window;
import android.view.WindowManager;
import mlxy.utils.Dev;
public class BottomDialog extends Dialog {
private AddressSelector selector;
public BottomDialog(Context context) {
super(context, R.style.bottom_dialog);
init(context);
}
public BottomDialog(Context context, int themeResId) {
super(context, themeResId);
init(context);
}
public BottomDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
init(context);
}
private void init(Context context) {
selector = new AddressSelector(context);
setContentView(selector.getView());
Window window = getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = Dev.dp2px(context, 256);
window.setAttributes(params);
window.setGravity(Gravity.BOTTOM);
}
public void setOnAddressSelectedListener(OnAddressSelectedListener listener) {
this.selector.setOnAddressSelectedListener(listener);
}
public static BottomDialog show(Context context) {
return show(context, null);
}
public static BottomDialog show(Context context, OnAddressSelectedListener listener) {
BottomDialog dialog = new BottomDialog(context, R.style.bottom_dialog);
dialog.selector.setOnAddressSelectedListener(listener);
dialog.show();
return dialog;
}
}
底部弹窗
package chihane.jdaddressselector;
import android.content.Context;
import com.raizlabs.android.dbflow.config.FlowConfig;
import com.raizlabs.android.dbflow.config.FlowManager;
import com.raizlabs.android.dbflow.list.FlowQueryList;
import com.raizlabs.android.dbflow.sql.language.SQLite;
import java.util.ArrayList;
import chihane.jdaddressselector.model.City;
import chihane.jdaddressselector.model.City_Table;
import chihane.jdaddressselector.model.County;
import chihane.jdaddressselector.model.County_Table;
import chihane.jdaddressselector.model.Province;
import chihane.jdaddressselector.model.Street;
import chihane.jdaddressselector.model.Street_Table;
public class DefaultAddressProvider implements AddressProvider {
public DefaultAddressProvider(Context context) {
FlowManager.init(new FlowConfig.Builder(context.getApplicationContext()).build());
}
@Override
public void provideProvinces(final AddressReceiver<Province> addressReceiver) {
final FlowQueryList<Province> provinceQueryList = SQLite.select()
.from(Province.class)
.flowQueryList();
addressReceiver.send(new ArrayList<>(provinceQueryList));
}
@Override
public void provideCitiesWith(int provinceId, final AddressReceiver<City> addressReceiver) {
final FlowQueryList<City> cityQueryList = SQLite.select()
.from(City.class)
.where(City_Table.province_id.eq(provinceId))
.flowQueryList();
addressReceiver.send(new ArrayList<>(cityQueryList));
}
@Override
public void provideCountiesWith(int cityId, final AddressReceiver<County> addressReceiver) {
final FlowQueryList<County> countyQueryList = SQLite.select()
.from(County.class)
.where(County_Table.city_id.eq(cityId))
.flowQueryList();
addressReceiver.send(new ArrayList<>(countyQueryList));
}
@Override
public void provideStreetsWith(int countyId, final AddressReceiver<Street> addressReceiver) {
final FlowQueryList<Street> streetQueryList = SQLite.select()
.from(Street.class)
.where(Street_Table.county_id.eq(countyId))
.flowQueryList();
addressReceiver.send(new ArrayList<>(streetQueryList));
}
}
从数据库取数据
package chihane.jdaddressselector;
import chihane.jdaddressselector.model.City;
import chihane.jdaddressselector.model.County;
import chihane.jdaddressselector.model.Province;
import chihane.jdaddressselector.model.Street;
public interface OnAddressSelectedListener {
void onAddressSelected(Province province, City city, County county, Street street);
}
选择地址结果回调接口
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/layout_tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/textViewProvince"
style="@style/tab" />
<TextView
android:id="@+id/textViewCity"
style="@style/tab" />
<TextView
android:id="@+id/textViewCounty"
style="@style/tab" />
<TextView
android:id="@+id/textViewStreet"
style="@style/tab" />
</LinearLayout>
<View
android:id="@+id/indicator"
android:layout_width="0dp"
android:layout_height="2dp"
android:layout_below="@+id/layout_tab"
android:background="@android:color/holo_red_light" />
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#e8e8e8" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<chihane.jdaddressselector.widget.UninterceptableListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@null" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>
</LinearLayout>
界面布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/selector_text_color_tab"
android:textSize="14sp" />
<ImageView
android:id="@+id/imageViewCheckMark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_toEndOf="@+id/textView"
android:layout_toRightOf="@+id/textView"
android:contentDescription="@string/desc_check_mark"
android:src="@drawable/ic_check"
android:visibility="gone" />
</RelativeLayout>
地址itempackage chihane.jdaddressselector.demo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import chihane.jdaddressselector.AddressSelector;
import chihane.jdaddressselector.BottomDialog;
import chihane.jdaddressselector.OnAddressSelectedListener;
import chihane.jdaddressselector.model.City;
import chihane.jdaddressselector.model.County;
import chihane.jdaddressselector.model.Province;
import chihane.jdaddressselector.model.Street;
import mlxy.utils.T;
public class MainActivity extends AppCompatActivity implements OnAddressSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FrameLayout frameLayout = (FrameLayout) findViewById(R.id.frameLayout);
AddressSelector selector = new AddressSelector(this);
selector.setOnAddressSelectedListener(this);
// selector.setAddressProvider(new TestAddressProvider());
assert frameLayout != null;
frameLayout.addView(selector.getView());
Button buttonBottomDialog = (Button) findViewById(R.id.buttonBottomDialog);
assert buttonBottomDialog != null;
buttonBottomDialog.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// BottomDialog.show(MainActivity.this, MainActivity.this);
BottomDialog dialog = new BottomDialog(MainActivity.this);
dialog.setOnAddressSelectedListener(MainActivity.this);
dialog.show();
}
});
}
@Override
public void onAddressSelected(Province province, City city, County county, Street street) {
String s =
(province == null ? "" : province.name) +
(city == null ? "" : "\n" + city.name) +
(county == null ? "" : "\n" + county.name) +
(street == null ? "" : "\n" + street.name);
T.showShort(this, s);
}
}
使用方法页面<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/darker_gray">
<FrameLayout
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="500dp"
android:layout_alignParentBottom="true" />
<Button
android:id="@+id/buttonBottomDialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BottomDialog" />
</RelativeLayout>
使用方法布局 上一篇: 栈的应用之逆波兰计算器练习