Campus address book function, collect and display the public contact information in the campus. It is often used in daily life. For example, when the water and electricity department has a problem, it needs to find a water and electricity master, an enrollment and employment office, a study and work office, etc.
Of course, for privacy reasons, personal cell phone numbers will not be collected and displayed. Only show office contact information and other numbers that can be found on the Internet or on campus.
Preface
The campus address book module aims to build a convenient campus information service platform, improve the campus information service, and provide a more convenient and safe service system for the management and maintenance of campus information.
(this paper is a simple implementation of this module, only about the display of address list style)
Serial articles
Github address: Science Division has campus APP
- Take you to a campus APP (I): Project Introduction
- Take you to a campus APP (2): application launch and welcome page
- Take you to a campus APP (3): user module (login, registration, etc.)
- A campus APP (4): APP framework and function design
- Take you to a campus APP (5): news page center module
- Take you to a c amp us APP (6): lost and found & second hand transaction module
- Hand in hand with you to roll up a campus APP (7): campus culture module (community activities & expression wall & illustration of campus)
- Take you to a campus APP (8): campus address book module
- Hand in hand with you to roll up a campus APP (9): curriculum module (simulated landing to access the curriculum information of the Academic Affairs Office)
- Take you to roll up a campus APP (10): APP general module (update, feedback, etc.)
Realization effect
Campus address book:
Analysis
- The data part of campus address book is relatively simple, including three main fields: name, department and contact information;
- The data in the address list needs to be sorted and grouped before being displayed;
Sort:
Sort by initials
==>Need to get Pinyin of initial character
==>Through tripartite Library TinyPinyin To achieve
Grouping:
It can be realized by customizing the ItemDecoration of RecycleView, and the display of the suspended window needs to be handled additionally
- The letter quick index list is displayed on the right side, associated with RecycleView, and can be associated with sliding
Implemented through custom controls
Realization
Note: the realization of this module mainly refers to the project of imitating Meizu address book of pony sprint, and on the basis of it, it optimizes the project, which pays tribute to the original author.
Github: Fake Meizu address book
Author: Pony run
Article: https://www.jianshu.com/p/7b7b7ee80c44
Database design
Field name | describe | type | Is the primary key? |
---|---|---|---|
objectId | Unique identification | String | yes |
name | Name and address | String | - |
department | department | String | - |
tel | Contact information | String | - |
Android implementation
Here are the main ideas of the realization of the campus address book module:
step 1: data sorting
After relying on TinyPinyin library, process the source data and add the content of setting indexTag field. Then sort according to the field;
public static void sortData(List<Teacher> list) { if (list == null || list.size() == 0) return; for (int i = 0; i < list.size(); i++) { Teacher bean = list.get(i); String tag = Pinyin.toPinyin(bean.getName().substring(0, 1).charAt(0)).substring(0, 1); if (tag.matches("[A-Z]")) { bean.setIndexTag(tag); } else { bean.setIndexTag("#"); } } Collections.sort(list, new Comparator<Teacher>() { @Override public int compare(Teacher o1, Teacher o2) { if ("#".equals(o1.getIndexTag())) { return 1; } else if ("#".equals(o2.getIndexTag())) { return -1; } else { return o1.getIndexTag().compareTo(o2.getIndexTag()); } } });
step 2: data grouping
After sorting the data, draw the category tags on the hover box and ItemView by customizing ItemDecoration
//Margin used to draw each ItemView @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { //Some codes are omitted int position = parent.getChildAdapterPosition(view); if (position == 0) { //The first data has bar outRect.set(0, dividerHeight, 0, 0); } else if (position > 0) { if (TextUtils.isEmpty(mBeans.get(position).getIndexTag())) return; //Different from the tag in the previous data, bar is displayed if (!mBeans.get(position).getIndexTag().equals(mBeans.get(position - 1).getIndexTag())) { outRect.set(0, dividerHeight, 0, 0); } } } //Used to draw the top suspension box @Override public void onDrawOver(Canvas canvas, RecyclerView parent, RecyclerView.State state) { int position = ((LinearLayoutManager) (parent.getLayoutManager())).findFirstVisibleItemPosition(); final int bottom = parent.getPaddingTop() + dividerHeight; mPaint.setColor(Color.WHITE); //Draw the extent of the hover box canvas.drawRect(parent.getLeft(), parent.getPaddingTop(), parent.getRight() - parent.getPaddingRight(), parent.getPaddingTop() + dividerHeight, mPaint); //Some codes are omitted mPaint.setTextSize(40); canvas.drawCircle(DpUtil.dp2px(mContext, 42.5f), bottom - dividerHeight / 2, 35, mPaint); mPaint.setColor(Color.WHITE); canvas.drawText(mBeans.get(position).getIndexTag(), DpUtil.dp2px(mContext, 42.5f), bottom - dividerHeight / 3, mPaint); } //Draw category tags on ItemView as needed @Override public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) { //Some codes are omitted final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); int position = params.getViewLayoutPosition(); if (position == 0) { //The first data has bar drawTitleBar(canvas, parent, child, mBeans.get(position), tagsStr.indexOf(mBeans.get(position).getIndexTag())); } else if (position > 0) { //Different from the tag in the previous data, bar is displayed if (!mBeans.get(position).getIndexTag().equals(mBeans.get(position - 1).getIndexTag())) { drawTitleBar(canvas, parent, child, mBeans.get(position), tagsStr.indexOf(mBeans.get(position).getIndexTag())); } } } }
step 3: customize the right index View
- Draw the right navigation bar letter:
@Override protected void onDraw(Canvas canvas) { //for loop to draw all navigation bar letters for (int i = 0; i < indexStr.length(); i++) { String textTag = indexStr.substring(i, i + 1); float xPos = (mWidth - mPaint.measureText(textTag)) / 2; canvas.drawText(textTag, xPos, singleHeight * (i + 1) + DpUtil.dp2px(mContext, TOP_MARGIN), mPaint); } }
- Handle sliding events:
In onTouchEvent, the sliding event is processed. When the fingers are sliding up and down, a circle on the left side will follow the sliding. Here, the user-defined IndexBar (IndexBar extensions ViewGroup, IndexBar contains SideBar) is used to process. When the SideBar sliding is in the MOVE state, a series of position parameters are transmitted to the IndexBar through ((IndexBar) getParent()).setDrawData()
@Override public boolean onTouchEvent(MotionEvent event) { //Handle push slide events switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //Press down mPaint.setColor(Color.BLACK); invalidate(); case MotionEvent.ACTION_MOVE: //Slide event.getY() to get the Y coordinate in the parent View, and then multiply the proportion to the total height by the total number of characters to get the position to be pressed int position = (int) ((event.getY() - getTop() - DpUtil.dp2px(mContext, 80)) / mHeight * indexStr.toCharArray().length); if (position >= 0 && position < indexStr.length()) { ((IndexBar) getParent()).setDrawData(event.getY(), String.valueOf(indexStr.toCharArray()[position]), position); if (listener != null) { listener.indexChanged(indexStr.substring(position, position + 1)); } } break; case MotionEvent.ACTION_UP: //lift ((IndexBar) getParent()).setTagStatus(false); mPaint.setColor(Color.GRAY); invalidate(); break; } return true; }
It mainly arranges SideBar to the far right in onLayout, and constantly changes the position of circle according to a series of position parameters transmitted from SideBar in onDraw,
Note here that the onDraw() method of the custom ViewGroup will not be called by default. If you want to execute the onDraw method, you can use the following two methods:
1. Set transparent background:
In the constructor: setBackgroundColor(Color.TRANSPARENT);
Or in xml: android:background="@color/transparent"
2. Or you can add setWillNotDraw(false) to the constructor;
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int childNum = getChildCount(); if (childNum <= 0) return; //Get SideBar View childView = getChildAt(0); childWidth = childView.getMeasuredWidth(); //Arrange SideBar to the far right childView.layout((mWidth - childWidth), 0, mWidth, mHeight); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (isShowTag) { //Constantly changing Paint color according to position ColorUtil.setPaintColor(mPaint, position); //Draw circles and text canvas.drawCircle((mWidth - childWidth) / 2, centerY, circleRadius, mPaint); mPaint.setColor(Color.WHITE); mPaint.setTextSize(80); canvas.drawText(tag, (mWidth - childWidth - mPaint.measureText(tag)) / 2, centerY - (mPaint.ascent() + mPaint.descent()) / 2, mPaint); } }
step 4: Associate RecycleView
sideBar.setIndexChangeListener(new SideBar.indexChangeListener() { @Override public void indexChanged(String tag) { if (TextUtils.isEmpty(tag) || contactList.size() <= 0) return; for (int i = 0; i < contactList.size(); i++) { if (tag.equals(contactList.get(i).getIndexTag())) { layoutManager.scrollToPositionWithOffset(i, 0); return; } } } });
So far, the campus address book module is basically completed.
In the example of this paper, we use multiple tripartite libraries TextDrawable,TinyPinyin ,Fake Meizu address book Wait, once again, I salute you guys!
If this article is helpful to you, I hope you can enjoy a little praise~