1. 程式人生 > >Android城市索引含定位和熱門城市(懸浮塊+右側字母索引)

Android城市索引含定位和熱門城市(懸浮塊+右側字母索引)

一、首先我們想要的效果是:

  • 在城市索引的列表能夠加個自定義頭部;
  • 有城市索引的字母懸浮塊;
  • 右側的字母索引導航;
  • 仿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,這