Android城市索引含定位和熱門城市(懸浮塊+右側字母索引)
阿新 • • 發佈:2019-02-20
一、首先我們想要的效果是:
- 在城市索引的列表能夠加個自定義頭部;
- 有城市索引的字母懸浮塊;
- 右側的字母索引導航;
- 仿os效果的當前位置索引提示框
我們先來看下效果:
下面的程式碼可能有點多,但是效果卻很不錯,請耐心往下看
這裡我是用的IndexableLayout控制元件做的
如果還是有不清楚的,可以去看我的Demo:CityProject
二、如何使用IndexableLayout:
- 需要加入第三方依賴庫:
compile 'me.yokeyword:indexablerecyclerview:1.3.0'
- 在.xml佈局中:
<me.yokeyword.indexablerv.IndexableLayout
android:id="@+id/indexableLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
app:indexBar_selectedTextColor="@color/black" //右側導航選中時的顏色
app:indexBar_textColor="@color/gray1" //右側導航字型顏色
app:indexBar_layout_width="40dp" //右側導航的寬度
app:indexBar_textSize="14sp" //右側導航的字型大小
app:indexBar_textSpace="5dp" />
- 在Activity中:
下面註釋寫的很清楚了,這裡我就不多做說明了
public class CityPickerActivity extends AppCompatActivity {
//IndexableLayout 的介面卡
private ContactAdapter mAdapter;
//自定義頭部adapter
private BannerHeaderAdapter mBannerHeaderAdapter;
//熱門城市的陣列
private String[] city = {"東莞","深圳","廣州","溫州","鄭州","金華","佛山" ,"上海","蘇州","杭州","長沙","中山"};
private IndexableLayout indexableLayout;
//熱門城市的介面卡
private CYBChangeCityGridViewAdapter cybChangeCityGridViewAdapter;
熱門城市的集合
private ArrayList<String> list;
//返回按鈕
private ImageView pic_contact_back;
private Intent intent;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pick_contact);
initview();
initAdapter();
onlisten();
}
public void initAdapter(){
mAdapter = new ContactAdapter(this);
indexableLayout.setAdapter(mAdapter);
//設定字母提示框為仿os居中
indexableLayout.setOverlayStyle_Center();
mAdapter.setDatas(initDatas());
// indexableLayout.setOverlayStyle_MaterialDesign(Color.RED); 設定提示框為仿聯絡人氣泡樣式
// 全字母排序。 排序規則設定為:每個字母都會進行比較排序;速度較慢
indexableLayout.setCompareMode(IndexableLayout.MODE_FAST);
// indexableLayout.addHeaderAdapter(new SimpleHeaderAdapter<>(mAdapter, "☆",null, null));
// 建構函式裡3個引數,分別對應 (IndexBar的字母索引, IndexTitle, 資料來源), 不想顯示哪個就傳null, 資料來源傳null時,代表add一個普通的View
// mMenuHeaderAdapter = new MenuHeaderAdapter("↑", null, initMenuDatas());
// indexableLayout.addHeaderAdapter(mMenuHeaderAdapter);
// 這裡BannerView只有一個Item, 新增一個長度為1的任意List作為第三個引數
List<String> bannerList = new ArrayList<>();
bannerList.add("");
mBannerHeaderAdapter = new BannerHeaderAdapter("↑", null, bannerList);
indexableLayout.addHeaderAdapter(mBannerHeaderAdapter);
}
public void initview(){
intent = getIntent();
pic_contact_back = (ImageView) findViewById(R.id.pic_contact_back);
indexableLayout = (IndexableLayout) findViewById(R.id.indexableLayout);
indexableLayout.setLayoutManager(new LinearLayoutManager(this));
}
public void onlisten(){
pic_contact_back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
mAdapter.setOnItemContentClickListener(new IndexableAdapter.OnItemContentClickListener<UserEntity>() {
@Override
public void onItemClick(View v, int originalPosition, int currentPosition, UserEntity entity) {
if (originalPosition >= 0) {
intent.putExtra("info", entity.getNick());
setResult(RESULT_OK, intent);
finish();
} else {
ToastUtil.showShort(CityPickerActivity.this, "選中Header/Footer:" + entity.getNick() + " 當前位置:" + currentPosition);
}
}
});
}
/**
* 自定義的Banner Header
*/
class BannerHeaderAdapter extends IndexableHeaderAdapter {
private static final int TYPE = 1;
//這裡傳的引數上面註釋有
public BannerHeaderAdapter(String index, String indexTitle, List datas) {
super(index, indexTitle, datas);
}
@Override
public int getItemViewType() {
return TYPE;
}
@Override
public RecyclerView.ViewHolder onCreateContentViewHolder(ViewGroup parent) {
View view = LayoutInflater.from(CityPickerActivity.this).inflate(R.layout.item_city_header, parent, false);
VH holder = new VH(view);
return holder;
}
@Override
public void onBindContentViewHolder(RecyclerView.ViewHolder holder, Object entity) {
// 資料來源為null時, 該方法不用實現
VH vh = (VH) holder;
list=new ArrayList<>();
for(int i = 0; i<city.length; i++){
list.add(city[i]);
}
System.out.println("------------city"+list);
cybChangeCityGridViewAdapter=new CYBChangeCityGridViewAdapter(CityPickerActivity.this, list);
// 繫結adpter
vh.head_home_change_city_gridview.setAdapter(cybChangeCityGridViewAdapter);
//熱門城市的item點選事件
vh.head_home_change_city_gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
intent.putExtra("info", list.get(position));
System.out.println("aaaaaayyyyyyyyy"+list.get(position));
setResult(RESULT_OK, intent);
finish();
}
});
//設定定位城市的點選事件
vh.item_header_city_dw.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intent.putExtra("bendi", MeNow.city);
setResult(RESULT_OK, intent);
finish();
}
});
}
private class VH extends RecyclerView.ViewHolder {
GridView head_home_change_city_gridview;
TextView item_header_city_dw;
public VH(View itemView) {
super(itemView);
head_home_change_city_gridview =(QGridView)itemView.findViewById(R.id.item_header_city_gridview);
item_header_city_dw = (TextView) itemView.findViewById(R.id.item_header_city_dw);
}
}
}
private List<UserEntity> initDatas() {
List<UserEntity> list = new ArrayList<>();
// 初始化資料,R.array.provinces是城市資源,下面有貼出資原始檔程式碼
List<String> contactStrings = Arrays.asList(getResources().getStringArray(R.array.provinces));
List<String> mobileStrings = Arrays.asList(getResources().getStringArray(R.array.provinces));
for (int i = 0; i < contactStrings.size(); i++) {
UserEntity contactEntity = new UserEntity(contactStrings.get(i), mobileStrings.get(i));
list.add(contactEntity);
}
return list;
}
}
Activity的.xml檔案中:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:background="@color/white"
android:elevation="3dp"
>
<ImageView
android:id="@+id/pic_contact_back"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/back"
android:padding="18dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="城市選擇"
android:layout_gravity="center_vertical"
android:textColor="@color/black"
android:textSize="18sp"
/>
</LinearLayout>
<me.yokeyword.indexablerv.IndexableLayout
android:id="@+id/indexableLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
app:indexBar_selectedTextColor="@color/black"
app:indexBar_textColor="@color/gray1"
app:indexBar_layout_width="40dp"
app:indexBar_textSize="14sp"
app:indexBar_textSpace="5dp" />
</LinearLayout>
values目錄下的R.arrays.xml城市資原始檔:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<string-array name="provinces">
<item>上海</item>
<item>北京</item>
<item>杭州</item>
<item>廣州</item>
...
</string-array>
</resources>
BannerHeaderAdapter其實就是相當於IndexableLayout的頭佈局,我這裡的定位城市和熱門城市就是通過新增這個頭部(BannerHeaderAdapter的item佈局):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="定位城市"
android:gravity="center_vertical"
android:paddingLeft="15dp"
android:textSize="@dimen/text_size_18"
android:textColor="@color/black"
/>
<TextView
android:id="@+id/item_header_city_dw"
android:layout_width="80dp"
android:layout_height="35dp"
android:textColor="@color/black"
android:gravity="center"
android:layout_marginLeft="15dp"
android:background="@drawable/sylayout_shop"
android:text="東莞"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/gray2"
android:layout_margin="15dp"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingBottom="5dp"
android:paddingLeft="15dp"
android:paddingRight="30dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="@color/black"
android:text="熱門城市"/>
<com.wzg.biswang.util.QGridView
android:id="@+id/item_header_city_gridview"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:numColumns="3"
android:stretchMode="columnWidth"
android:columnWidth="60dp"
android:verticalSpacing="10dp"
android:horizontalSpacing="15dp">
</com.wzg.biswang.util.QGridView>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/gray2"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="10dp"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:textSize="18sp"
android:textColor="@color/black"
android:layout_marginLeft="15dp"
android:gravity="center_vertical"
android:text="所有城市"/>
</LinearLayout>
ContactAdapter的介面卡也就是IndexableLayout的Adapter,這