概述
適配器模式可以把一個類的接口變換成客戶端所期待的另一種接口稿饰。從而使原本接口不匹配而無法在一起工作的兩個類能夠在一起工作。巴拉巴拉...
好了辖众,閑話少說嘁傀。適配器模式我們平時開發(fā)當中不一定常用(看個人風格),但是一定沒少見衫生。比如裳瘪,早前的 ListView就用了這模式,還有一個 SimpleAdapter罪针。再比如彭羹,我們現(xiàn)在常見的 RecyclerView的自定義 Adapter等等等等。
這次我們就結合例子泪酱,自己寫一個 Tablayout頂部導航標簽布局派殷,來看一看這個Adapter設計模式的用處。
-
創(chuàng)建 Adapter
首先墓阀,按照習慣毡惜,我們先創(chuàng)建一個 Adapter的抽象類:
public abstract class BaseAdapter {
// 定義標簽數(shù)量
protected abstract int getCount();
// 創(chuàng)建標簽的 View
protected abstract View getView(View parent, int index);
}
兩個方法分別用于獲取標簽的數(shù)量和創(chuàng)建標簽的 ItemView。然后我們再實現(xiàn)這個 BaseAdapter :
public class TabLayoutAdapter extends BaseAdapter{
private List<String> data;
public TabLayoutAdapter(){
data = new ArrayList<>();
}
public TabLayoutAdapter setData(List<String> data1){
data.clear();
data.addAll(data1);
// 鏈式結構
return this;
}
@Override
protected int getCount() {
return data.size();
}
@Override
protected View getView(View parent, int index) {
// 注釋1斯撮, 創(chuàng)建一個 Item
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_tab, null);
TextView textView = itemView.findViewById(R.id.tab_text);
textView.setText(data.get(index));
// 測試
if (index == 3) textView.setTextColor(Color.RED);
// 注釋 2 返回 Item
return itemView;
}
}
看到上面TabLayoutAdapter 實現(xiàn)類的結構经伙,如果我們經(jīng)常自定義RecyclerView的Adapter那一定不會陌生。注釋 1和注釋 2創(chuàng)建了 Layout的一個ItemView返回勿锅。數(shù)據(jù)長度和 ItemView返回之后就交由父布局處理了帕膜。接下來我們來創(chuàng)建一個簡單的TabLayout枣氧,處理一下這個 ItemView和ItemLength:
- TabLayout
/**
* 碧云天
*
* MyTabLayout
*/
public class MyTabLayout extends ScrollView {
private LinearLayout mLinearLayout;
private BaseAdapter mBaseAdapter;
private int itemCount;
public MyTabLayout(Context context) {
this(context, null);
}
public MyTabLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context, AttributeSet attrs, int defStyleAttr){
mLinearLayout = new LinearLayout(context);
mLinearLayout.setOrientation(HORIZONTAL);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
mLinearLayout.setLayoutParams(layoutParams);
//注釋 3, 我們這個 View繼承自 ScrollView垮刹,只能有一個字View
// 所以我們給它添加一個 LinearLayout作瞄,來裝所有的 ItemView
addView(mLinearLayout);
}
public void setAdapter(BaseAdapter baseAdapter) {
if (baseAdapter == null){
throw new NullPointerException("Adapter is null");
}
mBaseAdapter = baseAdapter;
itemCount = mBaseAdapter.getCount();
addItem();
}
private void addItem(){
for (int i = 0 ; i < itemCount; i ++){
//注釋 4 向布局 LinearLayout循環(huán)添加 所有 ItemView
mLinearLayout.addView(mBaseAdapter.getView(mLinearLayout, i));
}
}
}
這里的 MyTabLayout 繼承自 ScrollView ,這樣為了可以實現(xiàn)滑動危纫。因為 ScrollView 只能添加一個 子View或者一個子布局宗挥,無法添加所有的 ItemView。所以在上面注釋 3處我們給它添加一個LinearLayout种蝶,我們往LinearLayout里添加 ItemView契耿。在 setAdapter之后,注釋 4的地方我們循環(huán)添加 ItemView螃征。
- 使用
定義好了搪桂,下面就開始使用了。按照步驟盯滚,應該先準備好數(shù)據(jù)的數(shù)組竖幔。然后創(chuàng)建一個 Adapter對象税娜,給 Adapter對象設置數(shù)據(jù)监署。最后調(diào)用 TabLayout的 setAdapter方法設置適配器:
public class MainActivity extends AppCompatActivity {
private MyTabLayout mTableLayout;
private List<String> data = new ArrayList<>();
private BaseAdapter mTabLayoutAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTableLayout = findViewById(R.id.my_tab);
data.add("首頁");
data.add("手機");
data.add("美妝");
data.add("運動");
data.add("食品");
init();
}
private void init(){
mTabLayoutAdapter = new TabLayoutAdapter().setData(data);
// 設置適配器
mTableLayout.setAdapter(mTabLayoutAdapter);
}
}
效果:
當然杭煎,我們這次寫的這個 TabLayout這個例子是非常low的。因為這次講的不是自定義 View的東西背率,而是用例子實現(xiàn)一下 Adapter設計模式话瞧。主要講設計模式,所以自定義布局這次就不再優(yōu)化了寝姿。
Demo :AdapterDesign