0
点赞
收藏
分享

微信扫一扫

Android系统联系人全特效实现(上),分组导航和挤压动画,想跳槽涨薪的必看

黄昏孤酒 2022-03-19 阅读 55

android:layout_gravity="center_horizontal"
android:layout_marginLeft="10dip"
android:textColor="#ffffff"
android:textSize="13sp" />
</LinearLayout>

</RelativeLayout>

布局文件很简单,里面放入了一个 ListView,用于展示联系人信息。另外还在头部放了一个 LinearLayout,里面包含了一个 TextView,它的作用是在界面头部始终显示一个当前分组。

然后新建一个 contact_item.xml 的布局,这个布局用于在 ListView 中的每一行进行填充,代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<LinearLayoutandroid:id="@+id/sort_key_layout"
br/>android:id="@+id/sort_key_layout"
android:layout_height="18dip"
android:background="#303030" >

<TextViewandroid:id="@+id/sort_key"
br/>android:id="@+id/sort_key"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="10dip"
android:textColor="#ffffff"
android:textSize="13sp" />
</LinearLayout>

<LinearLayoutandroid:id="@+id/name_layout"
br/>android:id="@+id/name_layout"
and

Android系统联系人全特效实现(上),分组导航和挤压动画,想跳槽涨薪的必看

roid:layout_height="50dip" >

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:src="@drawable/icon" />

<TextViewandroid:id="@+id/name"
br/>android:id="@+id/name"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textColor="#ffffff"
android:textSize="22sp" />
</LinearLayout>

</LinearLayout>

在这个布局文件中,首先是放入了一个和前面完成一样的分组布局,因为不仅界面头部需要展示分组,在每个分组内的第一个无素之前都需要展示分组布局。然后是加入一个简单的 LinearLayout,里面包含了一个 ImageView 用于显示联系人头像,还包含一个 TextView 用于显示联系人姓名。

这样我们的布局文件就全部写完了,下面开始来真正地实现功能。

先从简单的开始,新建一个 Contact 实体类:

public class Contact {

/**

  • 联系人姓名
    */
    private String name;

/**

  • 排序字母
    */
    private String sortKey;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getSortKey() {
return sortKey;
}

public void setSortKey(String sortKey) {
this.sortKey = sortKey;
}

}

这个实体类很简单,只包含了联系人姓名和排序键。

接下来完成联系人列表适配器的编写,新建一个 ContactAdapter 类继承自 ArrayAdapter,加入如下代码:

public class ContactAdapter extends ArrayAdapter<Contact> {

/**

  • 需要渲染的item布局文件
    */
    private int resource;

/**

  • 字母表分组工具
    */
    private SectionIndexer mIndexer;

public ContactAdapter(Context context, int textViewResourceId, List<Contact> objects) {
super(context, textViewResourceId, objects);
resource = textViewResourceId;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
Contact contact = getItem(position);
LinearLayout layout = null;
if (convertView == null) {
layout = (LinearLayout) LayoutInflater.from(getContext()).inflate(resource, null);
} else {
layout = (LinearLayout) convertView;
}
TextView name = (TextView) layout.findViewById(R.id.name);
LinearLayout sortKeyLayout = (LinearLayout) layout.findViewById(R.id.sort_key_layout);
TextView sortKey = (TextView) layout.findViewById(R.id.sort_key);
name.setText(contact.getName());
int section = mIndexer.getSectionForPosition(position);
if (position == mIndexer.getPositionForSection(section)) {
sortKey.setText(contact.getSortKey());
sortKeyLayout.setVisibility(View.VISIBLE);
} else {
sortKeyLayout.setVisibility(View.GONE);
}
return layout;
}

/**

  • 给当前适配器传入一个分组工具。
  • @param indexer
    */
    public void setIndexer(SectionIndexer indexer) {
    mIndexer = indexer;
    }

}

上面的代码中,最重要的就是 getView 方法,在这个方法中,我们使用 SectionIndexer 的 getSectionForPosition 方法,通过当前的 position 值拿到了对应的 section 值,然后再反向通过刚刚拿到的 section 值,调用 getPositionForSection 方法,取回新的 position 值。如果当前的 position 值和新的 position 值是相等的,那么我们就可以认为当前 position 的项是某个分组下的第一个元素,我们应该将分组布局显示出来,而其它的情况就应该将分组布局隐藏。

最后我们来编写程序的主界面,打开或新建 MainActivity 作为程序的主界面,代码如下所示:

public class MainActivity extends Activity {

/**

  • 分组的布局
    */
    private LinearLayout titleLayout;

/**

  • 分组上显示的字母
    */
    private TextView title;

/**

  • 联系人ListView
    */
    private ListView contactsListView;

/**

  • 联系人列表适配器
    */
    private ContactAdapter adapter;

/**

  • 用于进行字母表分组
    */
    private AlphabetIndexer indexer;

/**

  • 存储所有手机中的联系人
    */
    private List<Contact> contacts = new ArrayList<Contact>();

/**

  • 定义字母表的排序规则
    */
    private String alphabet = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ";

/**

  • 上次第一个可见元素,用于滚动时记录标识。
    */
    private int lastFirstVisibleItem = -1;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = new ContactAdapter(this, R.layout.contact_item, contacts);
titleLayout = (LinearLayout) findViewById(R.id.title_layout);
title = (TextView) findViewById(R.id.title);
contactsListView = (ListView) findViewById(R.id.contacts_list_view);
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
Cursor cursor = getContentResolver().query(uri,
new String[] { "display_name", "sort_key" }, null, null, "sort_key");
if (cursor.moveToFirst()) {
do {
String name = cursor.getString(0);
String sortKey = getSortKey(cursor.getString(1));
Contact contact = new Contact();
contact.setName(name);
contact.setSortKey(sortKey);
contacts.add(contact);
} while (cursor.moveToNext());
}
startManagingCursor(cursor);
indexer = new AlphabetIndexer(cursor, 1, alphabet);
adapter.setIndexer(indexer);
if (contacts.size() > 0) {
setupContactsListView();
}

结语

看到这篇文章的人不知道有多少是和我一样的Android程序员。

35岁,这是我们这个行业普遍的失业高发阶段,这种情况下如果还不提升自己的技能,进阶发展,我想,很可能就是本行业的职业生涯的终点了。

我们要有危机意识,切莫等到一切都成定局时才开始追悔莫及。只要有规划的,有系统地学习,进阶提升自己并不难,给自己多充一点电,你才能走的更远。

千里之行始于足下。这是上小学时,那种一元钱一个的日记本上每一页下面都印刷有的一句话,当时只觉得这句话很短,后来渐渐长大才慢慢明白这句话的真正的含义。

有了学习的想法就赶快行动起来吧,不要被其他的事情牵绊住了前行的脚步。不要等到裁员时才开始担忧,不要等到面试前一晚才开始紧张,不要等到35岁甚至更晚才开始想起来要学习要进阶。

给大家一份系统的Android学习进阶资料,希望这份资料可以给大家提供帮助。
Android系统联系人全特效实现(上),分组导航和挤压动画,想跳槽涨薪的必看

举报

相关推荐

0 条评论