日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

android开发地址选择器,Android地址选择器 类似于京东的地址选择

發(fā)布時(shí)間:2025/3/21 Android 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android开发地址选择器,Android地址选择器 类似于京东的地址选择 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

簡(jiǎn)介

最近東西寫的挺多的,這不又要弄一個(gè)類似于京東的地址選擇器,然后剛開始我是不愿意自己去寫的,這東西真的是浪費(fèi)時(shí)間。但是下班后回到家找了一圈沒找到一個(gè)合適的,好吧,那我就自己來(lái)封裝一個(gè)唄,反正生命在于coding,是吧~哈哈哈!先看看效果圖,不知道是不是大家想要的。區(qū)別就是京東是用在一個(gè)從下而上的彈窗里面的。

主要功能

1.大致分為三個(gè)模塊:頂部的Tab模塊,中間的移動(dòng)指示器模塊,還有就是下面的list了。

2.支持點(diǎn)擊數(shù)據(jù)后自動(dòng)跳到下一個(gè)Tab

3.支持點(diǎn)擊Tab后回到當(dāng)前Tab的狀態(tài)

4.還有就是可以隨意設(shè)置你想要的。

還是來(lái)說(shuō)說(shuō)怎么用吧。

項(xiàng)目地址:http://www.apkbus.com/thread-600090-1-1.html

集成導(dǎo)入(gradle)

1.Add the JitPack repository to your build file .Add it in your root build.gradle at the end of repositories:allprojects?{

repositories?{????????????...

maven?{?url?'https://jitpack.io'?}

}

}

2.Add the dependencydependencies?{

compile?'com.github.Blincheng:AddressSelector:v1.0.4'

}

使用

XML直接使用

android:id="@+id/address"

android:layout_width="match_parent"

android:layout_height="match_parent">

Java中使用AddressSelector?addressSelector?=?(AddressSelector)?findViewById(R.id.address);

設(shè)置Tab數(shù)量addressSelector.setTabAmount(3);

也可以不設(shè)置,默認(rèn)3級(jí)。

設(shè)置數(shù)據(jù)列表的Itme回調(diào)OnItemClickListeneraddressSelector.setOnItemClickListener(new?OnItemClickListener()?{????????????@Override

public?void?itemClick(AddressSelector?addressSelector,?CityInterface?city,?int?tabPosition)?{

}

});

設(shè)置Tab的點(diǎn)擊事件回調(diào)OnTabSelectedListeneraddressSelector.setOnTabSelectedListener(new?AddressSelector.OnTabSelectedListener()?{????????????@Override

public?void?onTabSelected(AddressSelector?addressSelector,?AddressSelector.Tab?tab)?{

}????????????@Override

public?void?onTabReselected(AddressSelector?addressSelector,?AddressSelector.Tab?tab)?{

}

});

注意,一般來(lái)說(shuō)這兩個(gè)點(diǎn)擊事件都要設(shè)置,并且數(shù)據(jù)的處理一定要搞清楚。

其他的一些屬性的設(shè)置

此處表示很憂傷,剛才不知道按了什么快捷鍵,剛寫的東西全丟了!!!不開心

實(shí)現(xiàn)

現(xiàn)在我們開始說(shuō)說(shuō)實(shí)現(xiàn)方式吧,從需求上面來(lái)講,我們需要寫出來(lái)的東西具有以下幾點(diǎn):

1.有指示器(Tab),

2.有一條會(huì)動(dòng)的橫線

3.下方有個(gè)列表

4.上方的Tab和下方的列表都是可點(diǎn)擊的。

其實(shí),從功能角度實(shí)現(xiàn)上來(lái)講,其實(shí)我們用google提供的現(xiàn)成的控件堆以下,其實(shí)也可以寫出來(lái)。比如舉個(gè)例子啊,上面的tab就用google自己的TabLayout,下方的列表就用RecyclerView,然后把數(shù)據(jù)什么的綁定以下,點(diǎn)擊事件做一下,把異常處理掉,也能出來(lái),就是說(shuō)不方便二次使用。

然后實(shí)現(xiàn)思路:我這邊直接繼承LinearLayout,然后一個(gè)一個(gè)往里面addView就好,簡(jiǎn)單粗暴。

Tab的話可以繼承TextView,Line的話繼承View應(yīng)該也行,下面的列表就直接用RecyclerView。好了,看看如何實(shí)現(xiàn)吧。

Tab的實(shí)現(xiàn)

先thinking,我們的Tab需要有文字,選中狀態(tài),然后應(yīng)該還要一個(gè)index。看代碼:/**

*?標(biāo)簽控件

*?*/

public?class?Tab?extends?TextView{

private?int?index?=?0;????????private?int?TextSelectedColor?=?Color.parseColor("#11B57C");????????private?int?TextEmptyColor?=?Color.parseColor("#333333");????????/**

*?是否選中狀態(tài)

*?*/

private?boolean?isSelected?=?false;????????public?Tab(Context?context)?{????????????super(context);

init();

}????????public?Tab(Context?context,?AttributeSet?attrs)?{????????????super(context,?attrs);

init();

}????????public?Tab(Context?context,?AttributeSet?attrs,?int?defStyleAttr)?{????????????super(context,?attrs,?defStyleAttr);

init();

}????????private?void?init(){

setTextSize(15);

}????????@Override

public?void?setText(CharSequence?text,?BufferType?type)?{????????????if(isSelected)

setTextColor(TextSelectedColor);????????????else

setTextColor(TextEmptyColor);????????????super.setText(text,?type);

}????????@Override

public?void?setSelected(boolean?selected)?{

isSelected?=?selected;

setText(getText());

}????????public?int?getIndex()?{????????????return?index;

}????????public?void?setIndex(int?index)?{????????????this.index?=?index;

}????????public?void?resetState(){

isSelected?=?false;

setText(getText());

}????????public?void?setTextSelectedColor(int?textSelectedColor)?{

TextSelectedColor?=?textSelectedColor;

}????????public?void?setTextEmptyColor(int?textEmptyColor)?{

TextEmptyColor?=?textEmptyColor;

}

}

很簡(jiǎn)單,就是重寫一下setText,然后根據(jù)選中的狀態(tài)來(lái)設(shè)置對(duì)應(yīng)的顏色即可。

實(shí)現(xiàn)Line

本來(lái)想了一下直接用View也能實(shí)現(xiàn),但是后來(lái)想想既然要移動(dòng),有點(diǎn)小動(dòng)畫,外層既然用了線性布局,這邊的橫線還有長(zhǎng)度的問(wèn)題,所以也直接用橫向的線性布局了。如下:/**

*?橫線控件

*?*/

private?class?Line?extends?LinearLayout{

private?int?sum?=?3;????????private?int?oldIndex?=?0;????????private?int?nowIndex?=?0;????????private?View?indicator;????????private?int?SelectedColor?=?Color.parseColor("#11B57C");????????public?Line(Context?context)?{????????????super(context);

init(context);

}????????public?Line(Context?context,?AttributeSet?attrs)?{????????????super(context,?attrs);

init(context);

}????????public?Line(Context?context,?AttributeSet?attrs,?int?defStyleAttr)?{????????????super(context,?attrs,?defStyleAttr);

init(context);

}????????private?void?init(Context?context){

setOrientation(HORIZONTAL);

setLayoutParams(new?LayoutParams(

LayoutParams.MATCH_PARENT,6));

setWeightSum(tabAmount);

indicator=?new?View(context);

indicator.setLayoutParams(new?LayoutParams(0,LayoutParams.MATCH_PARENT,1));

indicator.setBackgroundColor(SelectedColor);

addView(indicator);

}????????public?void?setIndex(int?index){????????????int?onceWidth?=?getWidth()/sum;????????????this.nowIndex?=?index;

ObjectAnimator?animator?=?ObjectAnimator.ofFloat(indicator,?"translationX",?indicator.getTranslationX(),?(nowIndex-oldIndex)*onceWidth);

animator.setDuration(300);

animator.start();

}????????public?void?setSum(int?sum)?{????????????this.sum?=?sum;

}????????public?void?setSelectedColor(int?selectedColor)?{

SelectedColor?=?selectedColor;

}

}

其實(shí)和Tab差不多,唯一不同的是需要之前選中的oldIndex,因?yàn)楫吘褂袀€(gè)動(dòng)畫嘛。public?void?setIndex(int?index){????????????int?onceWidth?=?getWidth()/sum;????????????this.nowIndex?=?index;

ObjectAnimator?animator?=?ObjectAnimator.ofFloat(indicator,?"translationX",?indicator.getTranslationX(),?(nowIndex-oldIndex)*onceWidth);

animator.setDuration(300);

animator.start();

}

看看這個(gè)接口,在設(shè)置index的同時(shí),把移動(dòng)的動(dòng)畫也一起做了。

AddressSelectord 實(shí)現(xiàn)

因?yàn)橹熬拖牒糜美^承LinearLayout的形式,所以也簡(jiǎn)單粗暴,直接一層一層去addView是吧,需要注意的是,這邊有個(gè)這樣的方法:/**

*?得到一個(gè)新的tab對(duì)象

*?*/

private?Tab?newTab(CharSequence?text,boolean?isSelected){

Tab?tab?=?new?Tab(mContext);

tab.setLayoutParams(new?LayoutParams(0,LayoutParams.WRAP_CONTENT,1));

tab.setGravity(Gravity.CENTER);

tab.setPadding(0,40,0,40);

tab.setSelected(isSelected);

tab.setText(text);

tab.setTextEmptyColor(TextEmptyColor);

tab.setTextSelectedColor(TextSelectedColor);

tab.setOnClickListener(this);????????return?tab;

}

看出來(lái)了吧,其實(shí)就是去創(chuàng)建需要的Tab,然后把點(diǎn)擊事件等其他參數(shù)都設(shè)置好了,主要用來(lái)AddressSelectord 內(nèi)部來(lái)創(chuàng)建Tab時(shí)候用。

然后必要的屬性還是要提供接口設(shè)置的:/**

*?設(shè)置tab的數(shù)量,默認(rèn)3個(gè),不小于2個(gè)

*?@param?tabAmount?tab的數(shù)量

*?*/

public?void?setTabAmount(int?tabAmount)?{????????if(tabAmount?>=?2){????????????this.tabAmount?=?tabAmount;

init(mContext);

}????????else

throw?new?RuntimeException("AddressSelector?tabAmount?can?not?less-than?2?!");

}

需要設(shè)置當(dāng)前tab的數(shù)量,然后看這邊又調(diào)用了init()方法,也就是說(shuō)其實(shí)這個(gè)時(shí)候AddressSelectord 又重置了。所以在init()方法中有一個(gè)removeAllViews();?需要調(diào)用。

下邊兒列表的實(shí)現(xiàn)RecyclerView

然后一開始我就在想要不要提供什么Adapter可以讓大家自己來(lái)綁定數(shù)據(jù),然后又想了想,為了簡(jiǎn)單方便大家使用,所以我覺得還是暫時(shí)不寫Adapter了。但是想想每個(gè)item的Entity不應(yīng)該是死的,畢竟大家的項(xiàng)目還是不一樣的,所以我最終采取了一種方式去實(shí)現(xiàn)。public?interface?CityInterface?{

String?getCityName();

}

就是這個(gè)接口了,大家在設(shè)置數(shù)據(jù)源的時(shí)候,盡管設(shè)置自己的,然后唯一需要注意的是大家的 Item需要去實(shí)現(xiàn)這個(gè)接口,返回我列表需要展示的文本,我用來(lái)展示列表的內(nèi)容。只能要求大家做這么一點(diǎn)點(diǎn)了。所以在設(shè)置數(shù)據(jù)的時(shí)候也要求大家這么做了。/**

*?設(shè)置列表的數(shù)據(jù)源,設(shè)置后立即生效

*?*/

public?void?setCities(ArrayList?cities)?{????????if(cities?==?null||cities.size()?<=?0)????????????return;????????if(cities.get(0)?instanceof?CityInterface){????????????this.cities?=?cities;????????????if(addressAdapter?==?null){

addressAdapter?=?new?AddressAdapter();

list.setAdapter(addressAdapter);

}

addressAdapter.notifyDataSetChanged();

}else{????????????throw?new?RuntimeException("AddressSelector?cities?must?implements?CityInterface");

}

}

不然就簡(jiǎn)單粗暴拋出throw new RuntimeException("AddressSelector cities must implements CityInterface"

這樣就好說(shuō)了,我在setOnItemClickListener可以直接返回CityInterface,就解決一切問(wèn)題了。

最后就是把要開放的接口開放一下,測(cè)測(cè)調(diào)調(diào)~

總結(jié)

然后,其實(shí)也是很簡(jiǎn)單的,就是練練手,做一些讓自己和大家都覺得方便可行的事情。如果有什么地方有問(wèn)題,或者有更好的建議真的很歡迎大家多多提出建議和意見,還有一句話就是說(shuō)沒事不要閑著,要多動(dòng)動(dòng)。

總結(jié)

以上是生活随笔為你收集整理的android开发地址选择器,Android地址选择器 类似于京东的地址选择的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。