最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android自定義View實(shí)現(xiàn)字母導(dǎo)航欄的代碼

 更新時(shí)間:2016年09月28日 11:19:36   作者:Hensen_  
這篇文章主要介紹了Android自定義View實(shí)現(xiàn)字母導(dǎo)航欄的實(shí)例代碼,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下

思路分析:

1、自定義View實(shí)現(xiàn)字母導(dǎo)航欄

2、ListView實(shí)現(xiàn)聯(lián)系人列表

3、字母導(dǎo)航欄滑動(dòng)事件處理

4、字母導(dǎo)航欄與中間字母的聯(lián)動(dòng)

5、字母導(dǎo)航欄與ListView的聯(lián)動(dòng)

效果圖:

首先,我們先甩出主布局文件,方便后面代碼的說明

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical"> 
<EditText 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:background="@drawable/search_border" 
android:drawableLeft="@android:drawable/ic_menu_search" 
android:padding="8dp" /> 
<RelativeLayout 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 
<ListView 
android:id="@+id/lv" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:divider="@null" /> 
<TextView 
android:id="@+id/tv" 
android:layout_width="50dp" 
android:layout_height="50dp" 
android:layout_centerInParent="true" 
android:background="#888888" 
android:gravity="center" 
android:textColor="#000000" 
android:textSize="18dp" 
android:visibility="gone" /> 
<com.handsome.tulin.View.NavView 
android:id="@+id/nv" 
android:layout_width="20dp" 
android:layout_height="match_parent" 
android:layout_alignParentRight="true" 
android:layout_margin="16dp" /> 
</RelativeLayout> 
</LinearLayout>

步驟一:分析自定義字母導(dǎo)航欄

思路分析:

1、我們?cè)谑褂玫臅r(shí)候把寬設(shè)置為20dp,高設(shè)置為填充父控件,所以這里獲取的寬度為20dp

2、通過循環(huán),畫出豎直的字母,每畫一次得重新設(shè)置一下顏色,因?yàn)槲覀冃枰粋€(gè)選中的字母顏色和默認(rèn)不一樣

public class NavView extends View { 
private Paint textPaint = new Paint(); 
private String[] s = 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", "#"}; 
//鼠標(biāo)點(diǎn)擊、滑動(dòng)時(shí)選擇的字母 
private int choose = -1; 
//中間的文本 
private TextView tv; 
public NavView(Context context, AttributeSet attrs) { 
super(context, attrs); 
} 
public NavView(Context context) { 
super(context); 
} 
public NavView(Context context, AttributeSet attrs, int defStyleAttr) { 
super(context, attrs, defStyleAttr); 
} 
private void initPaint() { 
textPaint.setTextSize(20); 
textPaint.setAntiAlias(true); 
textPaint.setColor(Color.BLACK); 
} 
@Override 
protected void onDraw(Canvas canvas) { 
super.onDraw(canvas); 
//畫字母 
drawText(canvas); 
} 
/** 
* 畫字母 
* 
* @param canvas 
*/ 
private void drawText(Canvas canvas) { 
//獲取View的寬高 
int width = getWidth(); 
int height = getHeight(); 
//獲取每個(gè)字母的高度 
int singleHeight = height / s.length; 
//畫字母 
for (int i = 0; i < s.length; i++) { 
//畫筆默認(rèn)顏色 
initPaint(); 
//高亮字母顏色 
if (choose == i) { 
textPaint.setColor(Color.RED); 
} 
//計(jì)算每個(gè)字母的坐標(biāo) 
float x = (width - textPaint.measureText(s[i])) / 2; 
float y = (i + 1) * singleHeight; 
canvas.drawText(s[i], x, y, textPaint); 
//重置顏色 
textPaint.reset(); 
} 
} 
}

步驟二:ListView實(shí)現(xiàn)聯(lián)系人列表

思路分析:

1、在主Activity中,定義一個(gè)數(shù)據(jù)數(shù)組,使用工具類獲取數(shù)組的第一個(gè)字母,使用Collections根據(jù)第一個(gè)字母進(jìn)行排序,由于工具類有點(diǎn)長,就不貼出來了。

2、創(chuàng)建一個(gè)ListView子布局,創(chuàng)建一個(gè)Adapter進(jìn)行填充。

主布局:

public class MainActivity extends AppCompatActivity { 
private TextView tv; 
private ListView lv; 
private NavView nv; 
private List<User> list; 
private UserAdapter adapter; 
private String[] name = new String[]{ 
"潘粵明", "戴軍", "薛之謙", "藍(lán)雨", "任泉", "張杰", "秦俊杰", 
"陳坤", "田亮", "夏雨", "保劍鋒", "陸毅", "喬振宇", "吉杰", "郭敬明", "巫迪文", "歡子", "井柏然", 
"左小祖咒", "段奕宏", "毛寧", "樊凡", "湯潮", "山野", "陳龍", "侯勇", "俞思遠(yuǎn)", "馮紹峰", "崔健", 
"杜淳", "張翰", "彭坦", "柏栩栩", "蒲巴甲", "凌瀟肅", "毛方圓", "武藝", "耿樂", "錢泳辰"}; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.activity_main); 
initView(); 
initData(); 
} 
private void initView() { 
tv = (TextView) findViewById(R.id.tv); 
lv = (ListView) findViewById(R.id.lv); 
nv = (NavView) findViewById(R.id.nv); 
nv.setTextView(tv); 
} 
private void initData() { 
//初始化數(shù)據(jù) 
list = new ArrayList<>(); 
for (int i = 0; i < name.length; i++) { 
list.add(new User(name[i], CharacterUtils.getFirstSpell(name[i]).toUpperCase())); 
} 
//將拼音排序 
Collections.sort(list, new Comparator<User>() { 
@Override 
public int compare(User lhs, User rhs) { 
return lhs.getFirstCharacter().compareTo(rhs.getFirstCharacter()); 
} 
}); 
//填充ListView 
adapter = new UserAdapter(this, list); 
lv.setAdapter(adapter); 
} 
}

ListView子布局:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:background="#ffffff" 
android:orientation="vertical"> 
<TextView 
android:id="@+id/tv_firstCharacter" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:background="#DBDBDA" 
android:padding="8dp" 
android:text="A" 
android:textColor="#000000" 
android:textSize="14dp" /> 
<TextView 
android:id="@+id/tv_name" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:background="#ffffff" 
android:padding="8dp" 
android:text="張棟梁" 
android:textColor="#2196F3" 
android:textSize="14dp" /> 
</LinearLayout>

Adapter:

public class UserAdapter extends BaseAdapter { 
private List<User> list; 
private User user; 
private LayoutInflater mInflater; 
private Context context; 
public UserAdapter(Context context, List<User> list) { 
this.list = list; 
mInflater = LayoutInflater.from(context); 
this.context = context; 
} 
@Override 
public int getCount() { 
return list.size(); 
} 
@Override 
public Object getItem(int position) { 
return list.get(position); 
} 
@Override 
public long getItemId(int position) { 
return position; 
} 
@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
if (convertView == null) { 
convertView = mInflater.inflate(R.layout.adapter_user, null); 
} 
ViewHolder holder = getViewHolder(convertView); 
user = list.get(position); 
if (position == 0) { 
//第一個(gè)數(shù)據(jù)要顯示字母和姓名 
holder.tv_firstCharacter.setVisibility(View.VISIBLE); 
holder.tv_firstCharacter.setText(user.getFirstCharacter()); 
holder.tv_name.setText(user.getUsername()); 
} else { 
//其他數(shù)據(jù)判斷是否為同個(gè)字母,這里使用Ascii碼比較大小 
if (CharacterUtils.getCnAscii(list.get(position - 1).getFirstCharacter().charAt(0)) < 
CharacterUtils.getCnAscii(user.getFirstCharacter().charAt(0))) { 
//后面字母的值大于前面字母的值,需要顯示字母 
holder.tv_firstCharacter.setVisibility(View.VISIBLE); 
holder.tv_firstCharacter.setText(user.getFirstCharacter()); 
holder.tv_name.setText(user.getUsername()); 
} else { 
//后面字母的值等于前面字母的值,不顯示字母 
holder.tv_firstCharacter.setVisibility(View.GONE); 
holder.tv_name.setText(user.getUsername()); 
} 
} 
return convertView; 
} 
/** 
* 獲得控件管理對(duì)象 
* 
* @param view 
* @return 
*/ 
private ViewHolder getViewHolder(View view) { 
ViewHolder holder = (ViewHolder) view.getTag(); 
if (holder == null) { 
holder = new ViewHolder(view); 
view.setTag(holder); 
} 
return holder; 
} 
/** 
* 控件管理類 
*/ 
private class ViewHolder { 
private TextView tv_firstCharacter, tv_name; 
ViewHolder(View view) { 
tv_firstCharacter = (TextView) view.findViewById(R.id.tv_firstCharacter); 
tv_name = (TextView) view.findViewById(R.id.tv_name); 
} 
} 
/** 
* 通過字符查找位置 
* 
* @param s 
* @return 
*/ 
public int getSelectPosition(String s) { 
for (int i = 0; i < getCount(); i++) { 
String firChar = list.get(i).getFirstCharacter(); 
if (firChar.equals(s)) { 
return i; 
} 
} 
return -1; 
} 
}

步驟三:字母導(dǎo)航欄滑動(dòng)事件處理、字母導(dǎo)航欄與中間字母的聯(lián)動(dòng)

思路分析:

1、在自定義View中重寫dispatchTouchEvent處理滑動(dòng)事件,最后返回true。

2、在主Activity傳進(jìn)來一個(gè)TextView,在我們滑動(dòng)的時(shí)候設(shè)置Text,松開的時(shí)候消失Text。設(shè)置Text的時(shí)候需要計(jì)算Text的位置,并且滑過多的話會(huì)出現(xiàn)數(shù)組越界的問題,所以我們?cè)诶锩嫣幚頂?shù)組越界問題。

3、最后,提供一個(gè)接口,記錄我們滑到的字母,為了后面可以和ListView聯(lián)動(dòng)。

@Override 
public boolean dispatchTouchEvent(MotionEvent event) { 
//計(jì)算選中字母 
int index = (int) (event.getY() / getHeight() * s.length); 
//防止腳標(biāo)越界 
if (index >= s.length) { 
index = s.length - 1; 
} else if (index < 0) { 
index = 0; 
} 
switch (event.getAction()) { 
case MotionEvent.ACTION_DOWN: 
case MotionEvent.ACTION_MOVE: 
setBackgroundColor(Color.GRAY); 
//選中字母高亮 
choose = index; 
//出現(xiàn)中間文字 
tv.setVisibility(VISIBLE); 
tv.setText(s[choose]); 
//調(diào)用ListView連動(dòng)接口 
if (listener != null) { 
listener.touchCharacterListener(s[choose]); 
} 
//重繪 
invalidate(); 
break; 
default: 
setBackgroundColor(Color.TRANSPARENT); 
//取消選中字母高亮 
choose = -1; 
//隱藏中間文字 
tv.setVisibility(GONE); 
//重繪 
invalidate(); 
break; 
} 
return true; 
} 
public onTouchCharacterListener listener; 
public interface onTouchCharacterListener { 
void touchCharacterListener(String s); 
} 
public void setListener(onTouchCharacterListener listener) { 
this.listener = listener; 
} 
/** 
* 傳進(jìn)來一個(gè)TextView 
* 
* @param tv 
*/ 
public void setTextView(TextView tv) { 
this.tv = tv; 
}

步驟四:字母導(dǎo)航欄和ListView的聯(lián)動(dòng)

思路分析:

1、我們已經(jīng)通過接口傳遞過去了一個(gè)選擇的字母,和在adapter寫好了根據(jù)字母查詢position的方法,這個(gè)時(shí)候只要主Activity對(duì)自定義View設(shè)置監(jiān)聽,判斷即可。

//ListView連動(dòng)接口 
nv.setListener(new NavView.onTouchCharacterListener() { 
@Override 
public void touchCharacterListener(String s) { 
int position = adapter.getSelectPosition(s); 
if (position != -1) { 
lv.setSelection(position); 
} 
} 
});

以上所述是小編給大家介紹的Android自定義View實(shí)現(xiàn)字母導(dǎo)航欄的代碼,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Android應(yīng)用App更新實(shí)例詳解

    Android應(yīng)用App更新實(shí)例詳解

    現(xiàn)在一般的Android軟件都是需要不斷更新的,當(dāng)你打開某個(gè)app的時(shí)候,如果有新的版本,它會(huì)提示你有新版本需要更新。該項(xiàng)目實(shí)現(xiàn)的就是這個(gè)功能。下面跟著小編一起來看下吧
    2017-03-03
  • 自己實(shí)現(xiàn)Android View布局流程

    自己實(shí)現(xiàn)Android View布局流程

    這篇文章主要介紹了自己實(shí)現(xiàn)Android View布局流程,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下
    2021-03-03
  • Flutter進(jìn)階之實(shí)現(xiàn)動(dòng)畫效果(十)

    Flutter進(jìn)階之實(shí)現(xiàn)動(dòng)畫效果(十)

    這篇文章主要為大家詳細(xì)介紹了Flutter進(jìn)階之實(shí)現(xiàn)動(dòng)畫效果的第十篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • android wifi信號(hào)強(qiáng)度等級(jí)區(qū)分的修改介紹

    android wifi信號(hào)強(qiáng)度等級(jí)區(qū)分的修改介紹

    calculateSignalLevel為計(jì)算信號(hào)等級(jí)函數(shù),MAX_RSSI和MIN_RSSI分別為最強(qiáng)和最弱信號(hào)強(qiáng)度等級(jí)的信號(hào)強(qiáng)度閥值
    2013-06-06
  • android 之listview 優(yōu)化方法

    android 之listview 優(yōu)化方法

    這篇文章主要介紹了android 之listview 優(yōu)化方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-06-06
  • OpenGL Shader實(shí)例分析(4)閃光效果

    OpenGL Shader實(shí)例分析(4)閃光效果

    這篇文章主要為大家詳細(xì)介紹了OpenGL Shader實(shí)例分析第4篇,實(shí)現(xiàn)閃光效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • Android用于校驗(yàn)集合參數(shù)的小封裝示例

    Android用于校驗(yàn)集合參數(shù)的小封裝示例

    本篇文章主要介紹了Android-用于校驗(yàn)集合參數(shù)的小封裝示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • ViewPager2滑動(dòng)沖突解決方案

    ViewPager2滑動(dòng)沖突解決方案

    這篇文章主要介紹了ViewPager2滑動(dòng)沖突解決方案,幫助大家更好的進(jìn)行Android開發(fā),感興趣的朋友可以了解下
    2020-12-12
  • Android實(shí)現(xiàn)動(dòng)態(tài)高斯模糊效果

    Android實(shí)現(xiàn)動(dòng)態(tài)高斯模糊效果

    在Android開發(fā)中常常會(huì)用到高斯模糊,但有的時(shí)候我們可能會(huì)需要一個(gè)圖片以不同的模糊程度展現(xiàn)出來,那如何實(shí)現(xiàn)呢,一起通過本文來學(xué)習(xí)學(xué)習(xí)吧。
    2016-08-08
  • Android調(diào)節(jié)屏幕亮度實(shí)現(xiàn)代碼

    Android調(diào)節(jié)屏幕亮度實(shí)現(xiàn)代碼

    這篇文章主要介紹了Android調(diào)節(jié)屏幕亮度實(shí)現(xiàn)代碼,調(diào)節(jié)屏幕亮度時(shí),先設(shè)置當(dāng)前activity亮度,再并保存為系統(tǒng)亮度即可,本文分別給出兩個(gè)步驟的實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2015-05-05

最新評(píng)論

手游| 汉中市| 东辽县| 莱西市| 安庆市| 阿拉善左旗| 隆子县| 扬中市| 越西县| 西丰县| 比如县| 阿瓦提县| 太原市| 鹿邑县| 大兴区| 济阳县| 新民市| 巴彦淖尔市| 稻城县| 江津市| 临颍县| 靖边县| 呼伦贝尔市| 旬阳县| 娄底市| 吉安市| 廊坊市| 纳雍县| 铜陵市| 平谷区| 和田县| 岳阳县| 禹城市| 石家庄市| 克拉玛依市| 呼图壁县| 麻城市| 伊通| 滨海县| 木兰县| 陕西省|