Material Design中文版Code4APPPHP100UI4APP

开启辅助访问设为首页收藏本站快捷导航切换到宽版切换风格

石刚 | |我的 |签到打卡 |设置 |消息 |提醒(2) |退出

积分: 36 |用户组: 初级码农

  • 首页
  • 安卓源码
  • 开发工具
  • 技术博客
  • 求职招聘
  • VIP
  • QQ群
  • 线下活动
  • 任务
  • 创业生态
  • 帮助
  帖子 搜索

安卓巴士 - 安卓开发 - Android开发 - 安卓 - 移动互联网门户»首页›安卓巴士-安卓论坛›Android精品源码›Android 仿美团网,探索ListView的A-Z字母排序功能实现选 ...
1234567 / 7 页下一页

返回列表

查看: 157|回复: 33
  

[Android精品源码] Android 仿美团网,探索ListView的A-Z字母排序功能实现选择城市

[复制链接]

   
MrlLee
 成长值: 1020

2338

主题

2631

帖子

2万

安币

管理员

积分
3434

  • 发消息
电梯直达

楼主

 发表于 3 天前 | 只看该作者 |只看大图 

Android精品源码
封面图:
Android 仿美团网,探索ListView的A-Z字母排序功能实现选择城市记得在我刚开始接触到美团网的时候就对美团网这个城市定位、选择城市功能很感兴趣,觉得它做得很棒。有如下几个点:一:实现ListView的A-Z字母排序功能二:根据输入框的输入值改变来过滤搜索结果,如果输入框里面的值为空,更新为原来的列表,否则为过滤数据列表三:汉字转成拼音的功能,很多时候实现联系人或者城市列表等实现A-Z的排序功能,我们可以直接从数据库中获取他的汉字拼音,而对于一般的数据,我们怎么实现A-Z的排序,这里我使用了PinYin4j.jar将汉字转换为拼音.按照惯例先来看一下最终效果图:

接下来分析下整个功能模块的布局结构:(1)首先一个带删除按钮的EditText,我们在输入框中输入我们查找的城市可以自动过滤出最终的结果,当输入框中没有数据自动替换到原来的数据列表;(2)中间是当前定位的城市和热门的城市,其中热门城市使用到了GridView;(3)下面是一个ListView用来显示数据列表,右侧是一个字母索引表,当我们点击不同的字母,ListView会定位到该字母地方现在我们来看下项目结构图

按照项目中类的顺序来一一介绍1.PinYin4j.jar用于将汉字转换为拼音,你还可以使用其他方式将汉子转换为拼音,我之前有介绍过,这里就不详讲啦,探索PinYin4j.jar将汉字转换为拼音的基本用法2.CitySortModel一个实体类,一个显示的城市和相对应的拼音首字母

[Java] 查看源文件 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.adan.selectcitydome.view;
public class CitySortModel {
    private String name;//显示的数据
    private String sortLetters;//显示数据拼音的首字母
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSortLetters() {
        return sortLetters;
    }
    public void setSortLetters(String sortLetters) {
        this.sortLetters = sortLetters;
    }
}

3.EditTextWithDel类是自定义的一个带清除功能的输入框控件,也可以用Android原生的EditText,这个类上一篇博客有介绍,这里就不贴上代码了Android 带清除功能的输入框控件EditTextWithDel4.MyGridView类就是自定义GridView,主要是解决了在热门城市中嵌套Grideview的显示不完全的问题

[Java] 查看源文件 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.adan.selectcitydome.view;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.GridView;
/**
 * 自定义GridView,解决嵌套Grideview的显示不完全的问题
 */
public class MyGridView extends GridView {
    public MyGridView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    public MyGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public MyGridView(Context context) {
        super(context);
    }
    /**
     * 其中onMeasure函数决定了组件显示的高度与宽度;
     * makeMeasureSpec函数中第一个函数决定布局空间的大小,第二个参数是布局模式
     * MeasureSpec.AT_MOST的意思就是子控件需要多大的控件就扩展到多大的空间
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}

5.PinyinComparator类用来对ListView中的数据根据A-Z进行排序,前面两个if判断主要是将不是以汉字开头的数据放在后面

[Java] 查看源文件 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.adan.selectcitydome.view;
import java.util.Comparator;
/**
 * 用来对ListView中的数据根据A-Z进行排序,前面两个if判断主要是将不是以汉字开头的数据放在后面
 */
public class PinyinComparator implements Comparator<CitySortModel> {
    public int compare(CitySortModel o1, CitySortModel o2) {
        //这里主要是用来对ListView里面的数据根据ABCDEFG...来排序
        if (o1.getSortLetters().equals("@")
                || o2.getSortLetters().equals("#")) {
            return -1;
        } else if (o1.getSortLetters().equals("#")
                || o2.getSortLetters().equals("@")) {
            return 1;
        } else {
            return o1.getSortLetters().compareTo(o2.getSortLetters());
        }
    }
}

6.PinyinUtils类,就是第一点所讲的PinYin4j.jar用于将汉字转换为拼音啦,这里就不粘贴代码啦7.SideBar类就是ListView右侧的字母索引View,我们需要使用setTextView(TextView mTextDialog)来设置用来显示当前按下的字母的TextView,以及使用setOnTouchingLetterChangedListener方法来设置回调接口,在回调方法onTouchingLetterChanged(String s)中来处理不同的操作

[Java] 查看源文件 复制代码
?
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package com.adan.selectcitydome.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import com.adan.selectcitydome.R;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * ListView右侧的字母索引View
 */
public class SideBar extends View {
    public static String[] INDEX_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"};
    private OnTouchingLetterChangedListener onTouchingLetterChangedListener;
    private List<String> letterList;
    private int choose = -1;
    private Paint paint = new Paint();
    private TextView mTextDialog;
    public SideBar(Context context) {
        this(context, null);
    }
    public SideBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public SideBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }
    private void init() {
        setBackgroundColor(Color.parseColor("#F0F0F0"));
        letterList = Arrays.asList(INDEX_STRING);
    }
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int height = getHeight();// 获取对应高度
        int width = getWidth();// 获取对应宽度
        int singleHeight = height / letterList.size();// 获取每一个字母的高度
        for (int i = 0; i < letterList.size(); i++) {
            paint.setColor(Color.parseColor("#606060"));
            paint.setTypeface(Typeface.DEFAULT_BOLD);
            paint.setAntiAlias(true);
            paint.setTextSize(20);
            // 选中的状态
            if (i == choose) {
                paint.setColor(Color.parseColor("#4F41FD"));
                paint.setFakeBoldText(true);
            }
            // x坐标等于中间-字符串宽度的一半.
            float xPos = width / 2 - paint.measureText(letterList.get(i)) / 2;
            float yPos = singleHeight * i + singleHeight / 2;
            canvas.drawText(letterList.get(i), xPos, yPos, paint);
            paint.reset();// 重置画笔
        }
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        final int action = event.getAction();
        final float y = event.getY();// 点击y坐标
        final int oldChoose = choose;
        final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener;
        final int c = (int) (y / getHeight() * letterList.size());// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数.
        switch (action) {
            case MotionEvent.ACTION_UP:
                setBackgroundColor(Color.parseColor("#F0F0F0"));
                choose = -1;
                invalidate();
                if (mTextDialog != null) {
                    mTextDialog.setVisibility(View.GONE);
                }
                break;
            default:
                setBackgroundResource(R.drawable.sidebar_background);
                if (oldChoose != c) {
                    if (c >= 0 && c < letterList.size()) {
                        if (listener != null) {
                            listener.onTouchingLetterChanged(letterList.get(c));
                        }
                        if (mTextDialog != null) {
                            mTextDialog.setText(letterList.get(c));
                            mTextDialog.setVisibility(View.VISIBLE);
                        }
                        choose = c;
                        invalidate();
                    }
                }
                break;
        }
        return true;
    }
    public void setIndexText(ArrayList<String> indexStrings) {
        this.letterList = indexStrings;
        invalidate();
    }
    /**
     * 为SideBar设置显示当前按下的字母的TextView
     *
     * @param mTextDialog
     */
    public void setTextView(TextView mTextDialog) {
        this.mTextDialog = mTextDialog;
    }
    /**
     * 向外公开的方法
     *
     * @param onTouchingLetterChangedListener
     */
    public void setOnTouchingLetterChangedListener(
            OnTouchingLetterChangedListener onTouchingLetterChangedListener) {
        this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;
    }
    /**
     * 接口
     */
    public interface OnTouchingLetterChangedListener {
        void onTouchingLetterChanged(String s);
    }
}

8.CityAdapter就是热门城市中GridView的适配器

[Java] 查看源文件 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.adan.selectcitydome;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import java.util.List;
/**
 * @author: xiaolijuan
 * @description:
 * @projectName: SelectCityDome
 * @date: 2016-03-01
 * @time: 17:25
 */
public class CityAdapter extends ArrayAdapter<String> {
    /**
     * 需要渲染的item布局文件
     */
    private int resource;
    public CityAdapter(Context context, int textViewResourceId, List<String> objects) {
        super(context, textViewResourceId, objects);
        resource = textViewResourceId;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LinearLayout layout = null;
        if (convertView == null) {
            layout = (LinearLayout) LayoutInflater.from(getContext()).inflate(resource, null);
        } else {
            layout = (LinearLayout) convertView;
        }
        Button name = (Button) layout.findViewById(R.id.tv_city);
        name.setText(getItem(position));
        return layout;
    }
}

9.SortAdapter 数据的适配器类,这里我们需要用到的就是SectionIndexer接口,它能够有效地帮助我们对分组进行控制。使用SectionIndexer接口需要实现三个方法:getSectionForPosition(int position),getPositionForSection(int section),getSections(),我们只需要自行实现前面两个方法:(一)getSectionForPosition(int position)是根据ListView的position来找出当前位置所在的分组(二)getPositionForSection(int section)就是根据首字母的Char值来获取在该ListView中第一次出现该首字母的位置,也就是当前分组所在的位置

[Java] 查看源文件 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package com.adan.selectcitydome;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.SectionIndexer;
import android.widget.TextView;
import com.adan.selectcitydome.view.CitySortModel;
import java.util.List;
public class SortAdapter extends BaseAdapter implements SectionIndexer {
    private List<CitySortModel> list = null;
    private Context mContext;
    public SortAdapter(Context mContext, List<CitySortModel> list) {
        this.mContext = mContext;
        this.list = list;
    }
    /**
     * 当ListView数据发生变化时,调用此方法来更新ListView
     *
     * @param list
     */
    public void updateListView(List<CitySortModel> list) {
        this.list = list;
        notifyDataSetChanged();
    }
    public int getCount() {
        return this.list.size();
    }
    public Object getItem(int position) {
        return list.get(position);
    }
    public long getItemId(int position) {
        return position;
    }
    public View getView(final int position, View view, ViewGroup arg2) {
        ViewHolder viewHolder = null;
        final CitySortModel mContent = list.get(position);
        if (view == null) {
            viewHolder = new ViewHolder();
            view = LayoutInflater.from(mContext).inflate(R.layout.item_select_city, null);
            viewHolder.tvTitle = (TextView) view.findViewById(R.id.tv_city_name);
            view.setTag(viewHolder);
            viewHolder.tvLetter = (TextView) view.findViewById(R.id.tv_catagory);
        } else {
            viewHolder = (ViewHolder) view.getTag();
        }
        int section = getSectionForPosition(position);
        if (position == getPositionForSection(section)) {
            viewHolder.tvLetter.setVisibility(View.VISIBLE);
            viewHolder.tvLetter.setText(mContent.getSortLetters());
        } else {
            viewHolder.tvLetter.setVisibility(View.GONE);
        }
        viewHolder.tvTitle.setText(this.list.get(position).getName());
        return view;
    }
    final static class ViewHolder {
        TextView tvLetter;
        TextView tvTitle;
    }
    public int getSectionForPosition(int position) {
        return list.get(position).getSortLetters().charAt(0);
    }
    public int getPositionForSection(int section) {
        for (int i = 0; i < getCount(); i++) {
            String sortStr = list.get(i).getSortLetters();
            char firstChar = sortStr.toUpperCase().charAt(0);
            if (firstChar == section) {
                return i;
            }
        }
        return -1;
    }
    @Override
    public Object[] getSections() {
        return null;
    }
}

10.MainActivity 对EditTextWithDel设置addTextChangedListener监听,当输入框内容发生变化根据里面的值过滤ListView,里面的值为空显示原来的列表和给ListView添加表头等

[Java] 查看源文件 复制代码
?
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package com.adan.selectcitydome;
import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.adan.selectcitydome.view.CitySortModel;
import com.adan.selectcitydome.view.EditTextWithDel;
import com.adan.selectcitydome.view.PinyinComparator;
import com.adan.selectcitydome.view.PinyinUtils;
import com.adan.selectcitydome.view.SideBar;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MainActivity extends Activity {
    private ListView sortListView;
    private SideBar sideBar;
    private TextView dialog, mTvTitle;
    private SortAdapter adapter;
    private EditTextWithDel mEtCityName;
    private List<CitySortModel> SourceDateList;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initViews();
    }
    private void initViews() {
        mEtCityName = (EditTextWithDel) findViewById(R.id.et_search);
        sideBar = (SideBar) findViewById(R.id.sidrbar);
        dialog = (TextView) findViewById(R.id.dialog);
        mTvTitle = (TextView) findViewById(R.id.tv_title);
        sortListView = (ListView) findViewById(R.id.country_lvcountry);
        initDatas();
        initEvents();
        setAdapter();
    }
    private void setAdapter() {
        SourceDateList = filledData(getResources().getStringArray(R.array.provinces));
        Collections.sort(SourceDateList, new PinyinComparator());
        adapter = new SortAdapter(this, SourceDateList);
        sortListView.addHeaderView(initHeadView());
        sortListView.setAdapter(adapter);
    }
    private void initEvents() {
        //设置右侧触摸监听
        sideBar.setOnTouchingLetterChangedListener(new SideBar.OnTouchingLetterChangedListener() {
            @Override
            public void onTouchingLetterChanged(String s) {
                //该字母首次出现的位置
                int position = adapter.getPositionForSection(s.charAt(0));
                if (position != -1) {
                    sortListView.setSelection(position + 1);
                }
            }
        });
        //ListView的点击事件
        sortListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                mTvTitle.setText(((CitySortModel) adapter.getItem(position - 1)).getName());
                Toast.makeText(getApplication(), ((CitySortModel) adapter.getItem(position)).getName(), Toast.LENGTH_SHORT).show();
            }
        });
        //根据输入框输入值的改变来过滤搜索
        mEtCityName.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                //当输入框里面的值为空,更新为原来的列表,否则为过滤数据列表
                filterData(s.toString());
            }
            @Override
            public void afterTextChanged(Editable s) {
            }
        });
    }
    private void initDatas() {
        sideBar.setTextView(dialog);
    }
    private View initHeadView() {
        View headView = getLayoutInflater().inflate(R.layout.headview, null);
        GridView mGvCity = (GridView) headView.findViewById(R.id.gv_hot_city);
        String[] datas = getResources().getStringArray(R.array.city);
        ArrayList<String> cityList = new ArrayList<>();
        for (int i = 0; i < datas.length; i++) {
            cityList.add(datas[i]);
        }
        CityAdapter adapter = new CityAdapter(getApplicationContext(), R.layout.gridview_item, cityList);
        mGvCity.setAdapter(adapter);
        return headView;
    }
    /**
     * 根据输入框中的值来过滤数据并更新ListView
     *
     * @param filterStr
     */
    private void filterData(String filterStr) {
        List<CitySortModel> mSortList = new ArrayList<>();
        if (TextUtils.isEmpty(filterStr)) {
            mSortList = SourceDateList;
        } else {
            mSortList.clear();
            for (CitySortModel sortModel : SourceDateList) {
                String name = sortModel.getName();
                if (name.toUpperCase().indexOf(filterStr.toString().toUpperCase()) != -1 || PinyinUtils.getPingYin(name).toUpperCase().startsWith(filterStr.toString().toUpperCase())) {
                    mSortList.add(sortModel);
                }
            }
        }
        // 根据a-z进行排序
        Collections.sort(mSortList, new PinyinComparator());
        adapter.updateListView(mSortList);
    }
    private List<CitySortModel> filledData(String[] date) {
        List<CitySortModel> mSortList = new ArrayList<>();
        ArrayList<String> indexString = new ArrayList<>();
        for (int i = 0; i < date.length; i++) {
            CitySortModel sortModel = new CitySortModel();
            sortModel.setName(date[i]);
            String pinyin = PinyinUtils.getPingYin(date[i]);
            String sortString = pinyin.substring(0, 1).toUpperCase();
            if (sortString.matches("[A-Z]")) {
                sortModel.setSortLetters(sortString.toUpperCase());
                if (!indexString.contains(sortString)) {
                    indexString.add(sortString);
                }
            }
            mSortList.add(sortModel);
        }
        Collections.sort(indexString);
        sideBar.setIndexText(indexString);
        return mSortList;
    }
}

布局文件就不贴出来了,有兴趣的可以下载代码

石刚,如果您要查看本帖隐藏内容请回复
Android, 搜索结果, 汉字拼音, 汉字转换, 效果图

分享到:  QQ好友和群 腾讯微博 QQ空间 微信

收藏

相关帖子

  • • Android源码解析②:异步消息机制
  • • Android源码解析③:异步任务AsyncTask
  • • 封装了一个Android EditText登陆注册功能
  • • Android新控件design兼容包的使用demo
  • • Android RecyclerView 简化使用
  • • Android 自动更新/在线参数
  • • Android 信息检索
  • • Android使用PopupWindow完成各种dialog
  • • Android开发常用控件
  • • 基于高德地图Android API快速搭建用车解决方案的示例

                                                       安卓巴士帮你上头条!欢迎骚扰!
                                                       想当斑竹?直接联系  
                                                      QQ群:46871359,欢迎勾搭! 
                                                 点击关注微博!更多干货微博等着你!
 
回复

举报

   
chaoyue

62

主题

591

帖子

1466

安币

Android大神

学海无涯

积分
1552

  • 发消息
沙发

 发表于 3 天前 | 只看该作者

好好 学习了 确实不错
 
 
点评回复 支持 反对

举报

   
遗失的流年

0

主题

87

帖子

70

安币

程序猿

积分
133
  • 发消息
板凳

 发表于 3 天前 | 只看该作者

好好 学习了 确实不错
 
 
点评回复 支持 反对

举报

   
Mr_Zhao

2

主题

127

帖子

347

安币

攻城狮

积分
324

  • 发消息
地板

 发表于 3 天前 | 只看该作者

相当不错,感谢无私分享精神!
 
 
点评回复 支持 反对

举报

   
ricktians

28

主题

785

帖子

1211

安币

码皇(巴士元老)

小白

积分
3107
  • 发消息
5#

 发表于 3 天前 | 只看该作者

学习...学习...
 
 
点评回复 支持 反对

举报

   
einnius2012

3

主题

117

帖子

115

安币

攻城狮

积分
267

  • 发消息
6#

 发表于 3 天前 | 只看该作者

相当不错,感谢无私分享精神!
 
 
点评回复 支持 反对

举报

   
lwklwc

8

主题

108

帖子

835

安币

攻城狮

积分
228
  • 发消息
7#

 发表于 3 天前 | 只看该作者

看看!@!!!!!!!!!!!!
 
 
点评回复

举报

   
lwklwc

8

主题

108

帖子

835

安币

攻城狮

积分
228
  • 发消息
8#

 发表于 3 天前 | 只看该作者

我只是路过打酱油的。
 
 
点评回复

举报

   

1234567 / 7 页下一页

返回列表

 这里是快捷回复,赶紧试试哦: 感谢 需要 给力 支持 路过 威武 学习 精彩 精华 淡定 不明觉厉
高级模式

BColorImageLinkQuoteCodeSmilies|

本版积分规则

*滑动验证:
按住左边滑块,拖动完成上方拼图

发表回复  回帖后跳转到最后一页

联系我们

申请友链|站点统计|Archiver|手机版|安卓巴士 ( 粤ICP备15117877号 ) 站长统计

[Android精品源码] Android 仿美团网,探索ListView的A-Z字母排序功能实现选择城市相关推荐

  1. android精品源码,跑马灯图片浏览器归属地下载!

    android各种各样的跑马灯样式 android各种各样的跑马灯样式 Android高仿知乎的侧滑删除源码 Android高仿知乎的侧滑删除源码 渐变颜色渐变文字渐变图像Gradualshowcol ...

  2. android社交源码,原生仿微信社交社区即时通讯聊天双端APP源码开源 带PC客户端...

    野火IM是一套跨平台.核心功能开源的即时通讯解决方案,主要包含以下内容. | 仓库                                                         | ...

  3. android intent 源码,Android 基础之 IntentService 源码

    Android 基础之 IntentService 源码 Android,IntentService,源码 IntentService 位于 android.app 包下面,是 Service 的一个 ...

  4. android精品源码,下拉刷新效果高德地图五子棋游戏定制日历全民TV源码

    1.Android图片涂鸦 2.在AchartEngine的基础上进行功能扩展的图表,新增非常多的... 3.上拉刷新.下拉加载 4.实现多种下拉刷新效果.上拉加载更多以及配置自定义头... 5.高德 ...

  5. 【android精品源码系列】安卓线上购物商城

    安卓线上购物商城[源码推荐] 简介 效果演示 首页 分类 购物车 我的 获取方式 关于我 简介 分享一个非常优秀的Android商城,功能非常完备,主要功能有: 1.首页不同item展示商品,轮播图等 ...

  6. 【android精品源码系列】安卓音乐播放器

    安卓音乐播放器[源码推荐] 简介 效果演示 获取方式 关于我 简介 分享一个Android音乐播放器,除了基本的音乐播放功能,还集成了知乎日报.段子图片等功能.主要功能有: 1.音乐部分 2.知乎日报 ...

  7. android 点赞源码,android仿即刻点赞文字部分的自定义View的示例代码

    概述:在学习HenCoder的过程中,有一期是模仿优秀自定义View,有一个项目是仿即刻的点赞,后来原作者在点评中提到,需要将文字和图片分开来写,并且模仿者的动画实现由点杂乱.所以决定重现实现下文字部 ...

  8. android 倒计时 源码,Android倒计时 Android仿京东倒计时 android电商app源码倒计时源码...

    countdown 一个简单的计时器 提供了一些方法 设置margin public void setLinearLayoutMargin(int left, int top, int right, ...

  9. 怎么看android底层源码,Android 底层按键获取

    与用户交互的输入设备(触摸屏,键盘等)是获取用户意图的来源.由于硬件本身的物理特性及由各大硬件厂商的标准不一,这将导致我们从设备上获取到的键值存在一定的差异性,为了让系统能够正确处理用户的操作,我们就 ...

最新文章

  1. iOS超全开源框架、项目和学习资料汇总(1)UI篇
  2. javaweb项目启动后自动查询数据库并刷新数值
  3. Android PendingIntent的使用
  4. 雅马哈机器人左手右手系统_消防管件组装成机器人 PM值临界时会报警并自动喷淋...
  5. 闲话WPF之十(Dependency属性 [2] )
  6. 815 计算机专业基础综合,2018年华东理工大学信息科学与工程学院815计算机专业基础综合之计算机操作系统考研基础五套测试题...
  7. java不用插件播放媒体文件_java servlet不用插件上传文件:
  8. VMware pro 15 ubuntu简易安装虚拟机黑屏
  9. 计算机编码简介(ASCII、ANSI、EBCDIC、Unicode)
  10. mysql 连接其他数据库_普通用户从其他主机连接MySQL数据库
  11. Sound Studio for Mac - 音频编辑处理工具
  12. 修改计算机系统参数软件,机器码修改专家(修改电脑机器码工具) v2.0官方版
  13. 最值得拥有的免费Bootstrap后台管理模板
  14. 如何整合JIRA、FishEye、Crucible进行CodeReview
  15. JetBrains .idea项目目录泄露
  16. java触发器linux,Auto activation triggers for Java(代码提示)功能扩展
  17. JavaWeb - Request Response
  18. iphoneX系列手机在页面滚动时隐藏底部的操作栏
  19. python积木编程软件下载_积木编程软件-积木编程官方版下载-红软网
  20. 开源仿google plus的wordpress主题

热门文章

  1. 半导体“国产替代”加速,这款芯片制造的关键设备爆火!
  2. android 获取电流参数,Android编程实现添加低电流提醒功能的方法
  3. Rust权威指南之编写自动化测试
  4. ubuntu 18.04.02 + GTX1660 + CUDA_10.0 + CUDNN_7.6.4 安装脱坑记
  5. python输入格式一个不带小数点_Python输入input、输出print
  6. 使用springboot每日推送早安问候语到用户微信【部署篇】
  7. php框架 三维图展示,HTML5开发实例-3D全景(ThreeJs全景Demo) 详解(图)
  8. Linux内核设计与实现---模块
  9. linux删除历史文件
  10. 关于判断一个点是否落在矩形内