52.懸浮首字母指示器


1.示例代碼:
數據的處理流程:
(1)獲取服務器數據
(2)將數據源拼音化
(3)將數據源排序
(4)將數據源過濾掉大寫字母
適配器的顯示:
(1)長度爲1就是索引字母,加載索引Item
(2)長度不爲1就是數據源,加載數據源Item

這裏有一個疑問:加載不一樣佈局的時候,適配器的佈局彷佛不方便複用啊?怎麼破?

視圖的繪製流程:
(1) 根據屏幕高度,動態設置索引視圖的高度
(2)監聽索引視圖的手勢事件

/*更多品牌*/
public class A4_BrandActivity extends MyBaseActivity {

private String[] indexStr;// 索引視圖的數據
int height;// 索引視圖的字體高度
private String data[];//漢字數組
private String pinyinData[];//拼音數組
HashMap<String, String> chineseMap = new HashMap<String, String>();// 拼音-漢字的鍵值對
HashMap<String, Integer> idMap = new HashMap<String, Integer>();// 拼音-id的鍵值對
String nData[] = new String[]{};// 數據源,整合了索引字母
private HashMap<String, Integer> selector;// 存放含有索引字母的位置
MyAdapter adapter;
List<Brand> brandList;
List<String> nameList;
List<String> tempData = new ArrayList<String>();

@InjectView(R.id.layout)
LinearLayout layoutIndex;//懸浮索引視圖
@InjectView(R.id.tv)
TextView tv_show;//顯示選中的字母
@InjectView(R.id.listView1)
ListView listView;

@OnClick(R.id.bt_back)
public void doBack(View view) {
finish();
}

@OnItemClick(R.id.listView1)
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
EventBus.getDefault().post(new MyBaseEvent(MyEventEnum.GetBrandCarList, new getBrandCarListEvent(idMap.get(nData[arg2]))));
finish();
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_morebrand);
loadData();
}

/**
* 根據屏幕高度,動態設置索引視圖的高度
*/
public void onWindowFocusChanged(boolean hasFocus) {
// oncreate裏面執行下面的代碼沒反應,由於oncreate裏面獲得的getHeight=0
System.out
.println("layoutIndex.getHeight()=" + layoutIndex.getHeight());
height = layoutIndex.getHeight() / indexStr.length;
getIndexView();
}

private void loadData() {
MyHttpControl.getBrandList(new H.HttpListener() {
@Override
public void onSuccess(String s) {
try {
getBrandListResponse response = JSON.parseObject(s, getBrandListResponse.class);
brandList = response.getBrandList();
nameList = new ArrayList<String>();
for (int i = 0; i < brandList.size(); i++) {
nameList.add(brandList.get(i).getBrandName());
}
data = (String[]) nameList.toArray(new String[brandList.size()]);


LogUtil.e("data=" + JSON.toJSONString(data));

dataToPinyin();

LogUtil.e("pinyinData=" + JSON.toJSONString(pinyinData));
LogUtil.e("chineseMap=" + chineseMap.toString());
LogUtil.e("idMap=" + idMap.toString());

dataToSort();
LogUtil.e("nData=" + JSON.toJSONString(nData));

dataToFilter();
LogUtil.e("nData02=" + JSON.toJSONString(nData));


adapter = new MyAdapter(A4_BrandActivity.this);
listView.setAdapter(adapter);
} catch (Exception e) {
LogUtil.e("e=" + e.getMessage());
}


}

@Override
public void onFailure(Throwable throwable, String s) {

}
});

indexStr = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I",
"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X",
"Y", "Z"};
}

/**
* 1.將數據源拼音化
*/
private void dataToPinyin() {
pinyinData = new String[data.length];
for (int i = 0; i < data.length; i++) {
String pinyin = converterToPinYin(data[i]);
pinyinData[i] = pinyin;
chineseMap.put(pinyin, data[i]);
idMap.put(pinyin, brandList.get(i).getBrandId());
}

}

/**
* 2.將數據源排序
*/
public void dataToSort() {
TreeSet<String> set = new TreeSet<String>();
// 獲取初始化數據源中的首字母,添加到set
for (String string : pinyinData) {
set.add(String.valueOf(string.charAt(0)));
}
// 新數組的長度爲原數據加上set的大小
nData = new String[pinyinData.length + set.size()];
int i = 0;
for (String string : set) {
nData[i] = string;
i++;
}
// 將原數據拷貝到新數據中
System.arraycopy(pinyinData, 0, nData, set.size(), pinyinData.length);
Arrays.sort(nData, String.CASE_INSENSITIVE_ORDER);// 自動按照首字母排序
}

/**
* 3.將數據源過濾掉大寫字母
*/
private void dataToFilter() {
//過濾掉nData中的全部大寫的拼音
for (int i = 0; i < nData.length; i++) {
if (nData[i].length() == 1) {
char t = nData[i].charAt(0);
if (t <= 'Z' && t >= 'A') {
} else {
tempData.add(nData[i]);
}
} else {
tempData.add(nData[i]);
}

}
LogUtil.e("tempData=" + tempData.toString());
nData = (String[]) tempData.toArray(new String[tempData.size()]);
}

/**
* 繪製索引列表
*/
public void getIndexView() {
LinearLayout.LayoutParams params = new LayoutParams(
LayoutParams.WRAP_CONTENT, height);
// params.setMargins(10, 5, 10, 0);
for (int i = 0; i < indexStr.length; i++) {
final TextView tv = new TextView(this);
tv.setLayoutParams(params);
tv.setTextColor(0xffffffff);
tv.setText(indexStr[i]);
tv.setPadding(10, 0, 10, 0);
layoutIndex.addView(tv);
layoutIndex.setOnTouchListener(new OnTouchListener() {

@Override
public boolean onTouch(View v, MotionEvent event)

{
float y = event.getY();
int index = (int) (y / height);
if (index > -1 && index < indexStr.length) {// 防止越界
String key = indexStr[index];
if (selector.containsKey(key)) {
int pos = selector.get(key);
if (listView.getHeaderViewsCount() > 0) {// 防止ListView有標題欄,本例中沒有。
listView.setSelectionFromTop(
pos + listView.getHeaderViewsCount(), 0);
} else {
listView.setSelectionFromTop(pos, 0);// 滑動到第一項
}
tv_show.setVisibility(View.VISIBLE);
tv_show.setText(indexStr[index]);
}
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
layoutIndex.setBackgroundColor(Color
.parseColor("#232323"));
break;
case MotionEvent.ACTION_MOVE:

break;
case MotionEvent.ACTION_UP:
layoutIndex.setBackgroundColor(Color
.parseColor("#232323"));
tv_show.setVisibility(View.INVISIBLE);
break;
}
return true;
}
});
}
}

/**
* 漢語拼音轉換工具
*/
public String converterToPinYin(String chinese) {
String pinyinString = "";
char[] charArray = chinese.toCharArray();
// 根據須要定製輸出格式,我用默認的便可
HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
try {
// 遍歷數組,ASC碼大於128進行轉換
for (int i = 0; i < charArray.length; i++) {
if (charArray[i] > 128) {
// charAt(0)取出首字母
if (charArray[i] >= 0x4e00 && charArray[i] <= 0x9fa5) { // 判斷是否中文
pinyinString += PinyinHelper.toHanyuPinyinStringArray(
charArray[i], defaultFormat)[0];
} else { // 不是中文的打上未知,因此沒法處理韓文日本等等其餘文字
pinyinString += "?";
}
} else {
pinyinString += charArray[i];
}
}
return pinyinString;
} catch (BadHanyuPinyinOutputFormatCombination e) {
e.printStackTrace();
return null;
}
}

/**
* 自定義適配器
*/
private class MyAdapter extends BaseAdapter {
public MyAdapter(Context context) {
selector = new HashMap<String, Integer>();
for (int j = 0; j < indexStr.length; j++) {// 循環字母表,找出nData中對應字母的位置
for (int i = 0; i < nData.length; i++) {
if (nData[i].equals(indexStr[j].toLowerCase())) {
selector.put(indexStr[j], i);
}
}

}
}

@Override
public int getCount() {
// TODO Auto-generated method stub
return nData.length;
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return nData[position];
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}

@Override
public boolean isEnabled(int position) {
// TODO Auto-generated method stub
if (nData[position].length() == 1)// 若是是字母索引
return false;// 表示不能點擊
return super.isEnabled(position);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
String item = nData[position];
if (item.length() == 1) {
convertView = getLayoutInflater().inflate(R.layout.index, null);
TextView tv = (TextView) convertView
.findViewById(R.id.text_index);
tv.setText(item.toUpperCase());
} else {
convertView = getLayoutInflater().inflate(R.layout.item, null);
TextView tv = (TextView) convertView
.findViewById(R.id.text_brand);
tv.setText(chineseMap.get(item));// 顯示的是拼音對應的漢字

ImageView iv = (ImageView) convertView
.findViewById(R.id.img_brand);
if (position % 3 == 0) {
iv.setBackgroundResource(R.drawable.homepage_car_logo_01);
} else if (position % 3 == 1) {
iv.setBackgroundResource(R.drawable.homepage_car_logo_02);
} else {
iv.setBackgroundResource(R.drawable.homepage_car_logo_03);
}

}
return convertView;
}
}

}
2.佈局資源
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:clipToPadding="true"
android:fitsSystemWindows="true"
android:background="@color/yellow"
android:orientation="vertical">

<RelativeLayout
android:id="@+id/layout_head"
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="@color/yellow">

<ImageView

android:id="@+id/bt_back"
android:layout_width="22dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:padding="5dp"
android:src="@drawable/back" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="更多品牌"
android:textSize="18dp" />
</RelativeLayout>

<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#26353A">

<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#c3c3c3"
android:scrollbars="none"></ListView>

<TextView
android:id="@+id/tv"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_gravity="center"
android:background="#f0606060"
android:gravity="center"
android:text="A"
android:textColor="#ffffff"
android:textSize="30sp"
android:visibility="invisible" />

<LinearLayout
android:id="@+id/layout"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="right|center_vertical"
android:layout_marginBottom="15dp"
android:layout_marginRight="5dp"
android:layout_marginTop="15dp"
android:background="@drawable/shape_index"
android:gravity="center"
android:orientation="vertical"></LinearLayout>
</FrameLayout>

</LinearLayout>
附件1:漢字轉拼音須要用到的jar
pinyin4j-2.5.0.jar
附件2:這是我本身從服務器獲取到的數據
data.txt



相關文章
相關標籤/搜索