- 浏览: 720809 次
-
文章分类
- 全部博客 (324)
- 图片 (1)
- Javascript (25)
- Android (144)
- css (6)
- intellij (3)
- jquery (9)
- java (29)
- mysql (5)
- grails (1)
- groovy (1)
- Android Eclipse (2)
- linux (12)
- web (5)
- 算法 (2)
- 软件安装 (1)
- dedecms (12)
- centsos (6)
- tomcat (1)
- win 2003 (3)
- 杰奇 (1)
- window (1)
- loadrunner (3)
- QTP (38)
- VBS (33)
- Android 自动化 (12)
- python (3)
最新评论
-
masuweng:
Intellij 中javax.servlet.http.HttpServlet包导不进来 -
臧殿彬:
为什么我在主线程中定义也会出现这个bug?
java.lang.RuntimeException: Can't create handler inside thread that has not cal -
wpp1993:
...
http请求返回并解析json数据 -
javasea:
不错不错
socket阻塞与非阻塞,同步与异步、I/O模型 -
suyuwen1:
Apache2.4.x版wampserver本地php服务器如 ...
WAMPserver配置(允许外部访问、phpmyadmin设置为输入用户名密码才可登录等)
http://www.uml.org.cn/mobiledev/201110121.asp
http://blog.csdn.net/jiahui524/article/details/7785606
感谢这两位的博客:
模仿微信好友列表功能(数据从手机中读取),实现汉首字母排序筛选:
用到了一个pinyin4j-2.5.0.jar这个包
这个包的介绍:http://sourceforge.net/projects/pinyin4j/files/
其中还有一个 ContentResolver的知识点:
http://www.cnblogs.com/ruiyi1987/archive/2011/06/20/2084925.html
这篇文章中用到这样一个查询条件:
String[] proj1=new String[]{ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.HAS_PHONE_NUMBER,
ContactsContract.Contacts.LOOKUP_KEY};
ContactsContract.Contacts已经不推荐使用,现在推荐使用phone
下面是代码:
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <FrameLayout android:id="@+id/llParent" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ListView android:id="@+id/lvShow" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <TextView android:id="@+id/tvLetter" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/show_head_toast_bg" android:gravity="center" android:maxWidth="70dip" android:minWidth="70dip" android:padding="10dip" android:textColor="#99FFFFFF" android:textSize="50sp" > </TextView> <mypack.aaron.conact.MySideBar android:id="@+id/myView" android:layout_width="30dip" android:layout_height="fill_parent" android:layout_gravity="right" > </mypack.aaron.conact.MySideBar> </FrameLayout> </LinearLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:descendantFocusability="blocksDescendants" android:orientation="vertical"> <TextView android:id="@+id/tv_catalog" style="@style/MMListCatalog" android:layout_height="wrap_content" android:paddingRight="4.0dip" /> <LinearLayout android:id="@+id/contactitem_layout" style="@style/MMListItem" android:layout_height="56.0dip" android:background="@drawable/mm_listitem" android:paddingLeft="8.0dip" > <ImageView android:id="@+id/contactitem_avatar_iv" android:layout_width="40.0dip" android:layout_height="40.0dip" android:src="@drawable/default_avatar" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1.0" android:orientation="vertical" android:paddingLeft="8.0dip" > <TextView android:id="@+id/tv_nick" style="@style/MMFontTitleInList" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:text="姓名" /> <TextView android:id="@+id/tv_mobile" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:singleLine="true" android:text="13123456789" android:textColor="#666666" /> </LinearLayout> <ImageButton android:id="@+id/imgbtn_nav" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginRight="5dip" android:background="@drawable/nav_left" android:focusable="false" android:focusableInTouchMode="false" /> </LinearLayout> </LinearLayout>
style.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- 联系分组样式 --> <style name="MMListItem"> <item name="android:gravity">center_vertical</item> <item name="android:orientation">horizontal</item> <item name="android:paddingLeft">4.0dip</item> <item name="android:paddingTop">4.0dip</item> <item name="android:paddingRight">4.0dip</item> <item name="android:paddingBottom">4.0dip</item> <item name="android:layout_width">fill_parent</item> <item name="android:layout_height">wrap_content</item> </style> <style name="MMFriendListItem"> <item name="android:gravity">center_vertical</item> <item name="android:orientation">horizontal</item> <item name="android:paddingLeft">16.0dip</item> <item name="android:paddingTop">6.0dip</item> <item name="android:paddingRight">6.0dip</item> <item name="android:paddingBottom">6.0dip</item> <item name="android:layout_width">fill_parent</item> <item name="android:layout_height">wrap_content</item> </style> <style name="MMListCatalog"> <item name="android:textSize">14.0dip</item> <item name="android:textStyle">bold</item> <item name="android:textColor">#ff595c61</item> <item name="android:gravity">center_vertical</item> <item name="android:orientation">horizontal</item> <item name="android:background">#ffced2d7</item> <item name="android:paddingLeft">10.0dip</item> <item name="android:paddingTop">2.0dip</item> <item name="android:paddingBottom">2.0dip</item> <item name="android:layout_width">fill_parent</item> <item name="android:layout_height">wrap_content</item> </style> <style name="MMFontTitleInList"> <item name="android:textSize">16.0dip</item> <item name="android:textColor">#ff595c61</item> <item name="android:ellipsize">end</item> <item name="android:gravity">center_vertical</item> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> <item name="android:singleLine">true</item> </style> <style name="MMFontTipInList"> <item name="android:textSize">14.0dip</item> <item name="android:textColor">#fff</item> <item name="android:ellipsize">end</item> <item name="android:gravity">center_vertical</item> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> <item name="android:singleLine">true</item> </style> </resources>
PinyinUtils.java
这个java文件是生成汉字首字母拼音
public class PinyinUtils {
// 获得汉语拼音首字母 public static String getAlpha(String chines) { String pinyinName = ""; char[] nameChar = chines.toCharArray(); HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat(); defaultFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE); defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE); for (int i = 0; i < nameChar.length; i++) { if (nameChar[i] > 128) { try { pinyinName += PinyinHelper.toHanyuPinyinStringArray( nameChar[i], defaultFormat)[0].charAt(0); } catch (BadHanyuPinyinOutputFormatCombination e) { e.printStackTrace(); } } else { pinyinName += nameChar[i]; } } return pinyinName; } /** * 将字符串中的中文转化为拼音,其他字符不变 * * @param inputString * @return */ public static String getPingYin(String inputString) { HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat(); format.setCaseType(HanyuPinyinCaseType.LOWERCASE); format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); format.setVCharType(HanyuPinyinVCharType.WITH_V); char[] input = inputString.trim().toCharArray(); String output = ""; try { for (int i = 0; i < input.length; i++) { if (java.lang.Character.toString(input[i]).matches( "[\\u4E00-\\u9FA5]+")) { String[] temp = PinyinHelper.toHanyuPinyinStringArray( input[i], format); output += temp[0]; } else output += java.lang.Character.toString(input[i]); } } catch (BadHanyuPinyinOutputFormatCombination e) { e.printStackTrace(); } return output; } /** * 汉字转换位汉语拼音首字母,英文字符不变 * * @param chines * 汉字 * @return 拼音 */ public static String converterToFirstSpell(String chines) { String pinyinName = ""; char[] nameChar = chines.toCharArray(); HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat(); defaultFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE); defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE); for (int i = 0; i < nameChar.length; i++) { if (nameChar[i] > 128) { try { pinyinName += PinyinHelper.toHanyuPinyinStringArray( nameChar[i], defaultFormat)[0].charAt(0); } catch (BadHanyuPinyinOutputFormatCombination e) { e.printStackTrace(); } } else { pinyinName += nameChar[i]; } } return pinyinName; } }
MySideBar.java
右边拼音
public class MySideBar extends View{ OnTouchingLetterChangedListener onTouchingLetterChangedListener; // 26个字母 public static String[] b = { "#", "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" }; int choose = -1; Paint paint = new Paint(); public MySideBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public MySideBar(Context context, AttributeSet attrs) { super(context, attrs); } public MySideBar(Context context) { super(context); } /** * 重写这个方法 */ protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (showBkg) { canvas.drawColor(Color.parseColor("#40000000")); } int height = getHeight(); int width = getWidth(); int singleHeight = height / b.length; for (int i = 0; i < b.length; i++) { paint.setColor(Color.BLACK); // paint.setColor(Color.WHITE); paint.setTypeface(Typeface.DEFAULT_BOLD); paint.setAntiAlias(true); paint.setTextSize(20); if (i == choose) { paint.setColor(Color.parseColor("#3399ff")); paint.setFakeBoldText(true); } float xPos = width / 2 - paint.measureText(b[i]) / 2; float yPos = singleHeight * i + singleHeight; canvas.drawText(b[i], xPos, yPos, paint); paint.reset(); } } private boolean showBkg = false; @Override public boolean dispatchTouchEvent(MotionEvent event) { final int action = event.getAction(); final float y = event.getY(); final int oldChoose = choose; final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener; final int c = (int) (y / getHeight() * b.length); switch (action) { case MotionEvent.ACTION_DOWN: showBkg = true; if (oldChoose != c && listener != null) { if (c > 0 && c < b.length) { listener.onTouchingLetterChanged(b[c]); choose = c; invalidate(); } } break; case MotionEvent.ACTION_MOVE: if (oldChoose != c && listener != null) { if (c > 0 && c < b.length) { listener.onTouchingLetterChanged(b[c]); choose = c; invalidate(); } } break; case MotionEvent.ACTION_UP: showBkg = false; choose = -1; invalidate(); break; } return true; } @Override public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent(event); } /** * 向外公开的方法 * * @param onTouchingLetterChangedListener */ public void setOnTouchingLetterChangedListener( OnTouchingLetterChangedListener onTouchingLetterChangedListener) { this.onTouchingLetterChangedListener = onTouchingLetterChangedListener; } /** * 接口 * * @author coder * */ public interface OnTouchingLetterChangedListener { public void onTouchingLetterChanged(String s); } }
public class PinyinComparator implements Comparator{
/** 按首字母排序**/ @Override public int compare(Object o1, Object o2) { String str1 = PinyinUtils.getPingYin((String) o1); String str2 = PinyinUtils.getPingYin((String) o2); return str1.compareTo(str2); } // // @Override // public int compare(Object o1, Object o2) { // String str1 = PinyinUtils.getPingYin(((UserInfo) o1).getPy()); // String str2 = PinyinUtils.getPingYin(((UserInfo) o2).getPy()); // return str1.compareTo(str2); // } }
最后就是activity:
public class ContactsActivity extends Activity implements OnTouchingLetterChangedListener { private ListView lv_list; /**联系人显示名称**/ private static final int PHONES_DISPLAY_NAME_INDEX = 0; /**电话号码**/ private static final int PHONES_NUMBER_INDEX = 1; /**头像ID**/ private static final int PHONES_PHOTO_ID_INDEX = 2; /**联系人的ID**/ private static final int PHONES_CONTACT_ID_INDEX = 3; /**联系人名称**/ private ArrayList<String> mContactsName = new ArrayList<String>(); /**联系人头像**/ private ArrayList<String> mContactsNumber = new ArrayList<String>(); /**联系人头像**/ private ArrayList<Bitmap> mContactsPhonto = new ArrayList<Bitmap>(); /**拼音**/ private ArrayList<String> mPy=new ArrayList<String>(); /**左侧拼音字母**/ private MySideBar myView; /**显示到屏幕中间的拼音**/ private TextView overlay; private OverlayThread overlayThread = new OverlayThread(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); lv_list=(ListView)findViewById(R.id.lv_lsit); overlay=(TextView)findViewById(R.id.tvLetter); lv_list.setTextFilterEnabled(true); overlay.setVisibility(View.INVISIBLE);//默认隐藏 myView = (MySideBar) findViewById(R.id.myView); myView.setOnTouchingLetterChangedListener(this); ContentResolver resolver = getContentResolver(); String[] proj1=new String[]{Phone.DISPLAY_NAME, Phone.NUMBER,Phone.PHOTO_ID,Phone.CONTACT_ID, }; Cursor curContacts=resolver.query(Phone.CONTENT_URI,proj1, null, null, null); if(curContacts.getCount()>0){ while(curContacts.moveToNext()){ //得到手机号码 String phoneNumber = curContacts.getString(PHONES_NUMBER_INDEX); //当手机号码为空的或者为空字段 跳过当前循环 if (TextUtils.isEmpty(phoneNumber)){ continue; } //得到联系人名称 String contactName = curContacts.getString(PHONES_DISPLAY_NAME_INDEX); //拼音 String py=PinyinUtils.getAlpha(contactName); //得到联系人ID Long contactid = curContacts.getLong(PHONES_CONTACT_ID_INDEX); //得到联系人头像ID Long photoid = curContacts.getLong(PHONES_PHOTO_ID_INDEX); //得到联系人头像Bitamp Bitmap contactPhoto = null; //photoid 大于0 表示联系人有头像 如果没有给此人设置头像则给他一个默认的 if(photoid > 0 ) { Uri uri =ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,contactid); InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(resolver, uri); contactPhoto = BitmapFactory.decodeStream(input); }else { contactPhoto = BitmapFactory.decodeResource(getResources(), R.drawable.contact_photo); } mContactsName.add(contactName); mContactsPhonto.add(contactPhoto); mContactsNumber.add(phoneNumber); mPy.add(py); } Collections.sort(mContactsName, new PinyinComparator()); //ArrayList按首字母拼音排序 curContacts.close(); } ListViewAdapter ltAdapter=new ListViewAdapter(); lv_list.setAdapter(ltAdapter); } /**绑定数据**/ public class ListViewAdapter extends BaseAdapter{ @Override public int getCount() { // TODO Auto-generated method stub return mContactsName.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return position; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater inflater =getLayoutInflater(); // 使用View的对象itemView与R.layout.item关联 if(convertView==null){ convertView=inflater.inflate(R.layout.list_item, null); } // 通过findViewById()方法实例R.layout.item内各组件 TextView tvName = (TextView) convertView.findViewById(R.id.tv_nick); TextView tvPhone=(TextView) convertView.findViewById(R.id.tv_mobile); ImageView iv_pic = (ImageView) convertView.findViewById(R.id.contactitem_avatar_iv); TextView tv_catalog=(TextView)convertView.findViewById(R.id.tv_catalog); /*首字拼音*/ String catalog = PinyinUtils.converterToFirstSpell(mContactsName.get(position).substring(0, 1)); if(position==0){ tv_catalog.setVisibility(View.VISIBLE); tv_catalog.setText(catalog); }else { /*下一个汉字首字拼音,如果两个汉字的首字母相等,下一个汉字的tv_catalog隐藏,这里其实就是把相同首字母的汉字叠加在一起*/ String lastCatalog = PinyinUtils.converterToFirstSpell(mContactsName.get(position - 1)).substring(0,1); if (catalog.equals(lastCatalog)) { tv_catalog.setVisibility(View.GONE); } else { tv_catalog.setVisibility(View.VISIBLE); tv_catalog.setText(catalog); } } tvName.setText(mContactsName.get(position)); iv_pic.setImageBitmap(mContactsPhonto.get(position)); tvPhone.setText(mContactsNumber.get(position)); return convertView; } } /*下面是触摸左侧拼音*/ private Handler handler = new Handler() { }; private class OverlayThread implements Runnable { public void run() { overlay.setVisibility(View.GONE); } } /**字母触摸事件**/ @Override public void onTouchingLetterChanged(String s) { Log.i("coder", "s:" + s); overlay.setText(s); overlay.setVisibility(View.VISIBLE); handler.removeCallbacks(overlayThread); handler.postDelayed(overlayThread, 1000); if (alphaIndexer(s) > 0) { int position = alphaIndexer(s); Log.i("coder", "position:" + position); lv_list.setSelection(position); } } //根据 字母的值找到mPy存储的汉字首字母拼音的索引,listView中根据这个索引定位显示 public int alphaIndexer(String s) { int position = 0; for (int i = 0; i < mContactsPhonto.size(); i++) { if (mPy.get(i).startsWith(s)) { position = i; break; } } Log.i("coder", "i" + position + mPy.get(position)); return position; } }
经过了手机测试成功,代码比较臃肿,还没有实现输入筛选条件查询,正在研究中
发表评论
-
将博客搬至CSDN
2014-12-24 22:28 868将博客搬至CSDN -
[Android设计模式]Android退出应用程序终极方法
2014-01-08 16:41 684首先,我们将管理Activity的功能通过一个扩展的Appl ... -
android中activity的四种加载模式
2014-01-08 16:20 948一、何为加载模式 在android的多activit ... -
Android实现数据存储技术
2014-01-08 13:49 892本文介绍Android中的5种数据存储方式。 数据存 ... -
-Android各版本系统源代码下载
2014-01-07 16:39 915原文地址http://blog.csdn.net/wangj ... -
XmlPullParser解析xml文件
2014-01-07 15:55 23978XML解析三种方式 DOM 通用性强,它会将XML文 ... -
ListView实现二级菜单
2014-01-06 18:53 3057实现如上图所示的二级菜单: 1上面是通过两个ListVi ... -
三种方式实现自定义圆形进度条ProgressBar
2014-01-06 16:46 3404一、通过动画实现 定义res/anim/loading.x ... -
android屏幕适配不同的资源图片、布局
2014-01-06 16:35 12101、 资源图片的适配: 在android ... -
获取屏幕分辨率 及 dp 和 像素关系
2014-01-06 16:24 1823DisplayMetrics metric = new Di ... -
Android用Application设置全局变量以及使用
2014-01-03 16:44 821如果想在整个应用中使用全局变量,在java中一般是使用静态变 ... -
Android SDK各版本源码
2013-06-07 20:47 1445http://repository.grepcode.com ... -
在android系统中增加预编译apk(use BUILD_PREBUILT instead!. Stop)
2013-06-05 22:55 104231,在commom.mk(build/target/prod ... -
android out目录结构
2013-06-02 14:37 1527Android编译完成后,将 ... -
Android OpenGL ES 开发教程 从入门到精通
2013-05-25 09:17 1072Android OpenGL ES 简明开发教程 An ... -
自定义ContentProvider
2013-05-20 19:10 1517自定义ContentProvider,根据不同的条件查询不同 ... -
Broadcast Receiver(广播接收器)
2013-05-19 23:11 1102Braodcast Receiver顾名思义就是广播接收器, ... -
Android Service生命周期及用法!
2013-05-19 22:22 1094来自:http://blog.csdn.net/andro ... -
Androdi Droid Fu介绍
2013-05-19 10:01 1227Droid-Fu是啥 Droid ... -
自定义dialog 含listview(二)
2013-05-16 12:13 2288弹出一个半透明的listview dialog: publ ...
相关推荐
这个项目基于wanlong360599336的开源代码进行修改,修复了登录、好友列表获取、头像获取的问题,并实现了收发信息等核心功能。 首先,我们需要了解C#编程语言。C#是微软公司推出的一种面向对象的编程语言,它在.NET...
"Android 仿微信的通讯录"是一个项目,旨在模仿微信应用中的通讯录功能,让用户能够像在微信中一样管理和查找联系人。下面我们将深入探讨这个项目可能包含的关键技术点和实现细节。 1. **数据存储**: - **SQLite...
通过`wx.updateShareMenu`和`onShareAppMessage`方法,用户可以将喜欢的音乐分享给微信好友或朋友圈。 10. **性能优化**:在开发过程中,应考虑性能优化,比如避免无谓的网络请求、合理使用setData方法减少页面渲染...
这个名为“微信小程序-仿QQ”的项目,旨在模仿手机QQ的应用界面和功能,让用户体验到类似QQ的聊天和社交体验,但无需下载安装额外的应用程序。该项目基于微信小程序的官方文档、示例代码以及开发工具,为开发者提供...
3. **数据持久化**:为了保存用户的聊天记录、好友信息等,项目中会用到SQLite数据库或者SharedPreference来实现数据的存储和读取。理解SQLite的基本操作,如创建表、插入、查询、更新和删除数据,是必不可少的。 4...
《Android应用源码之高仿微信》是一款基于Android平台的开源项目,旨在为开发者提供一个模仿微信客户端的应用实例。这个项目对于想要学习Android开发,尤其是界面设计和功能实现的开发者来说,具有很高的参考价值。...
【描述】提到的内容进一步确认了项目的目标,即模仿微信的功能,这可能包括文字聊天、语音消息、图片分享、好友添加、群组聊天等功能。开发者可能已经实现了这些功能,以便学习者可以研究和理解如何在C++中实现类似...
5. **数据结构与算法**:在模拟微信功能时,可能会涉及好友列表、聊天记录等数据的存储和管理。这可能需要用到数组、链表等数据结构,以及排序、查找等算法。 6. **网络通信**:虽然这里没有明确提及,但真正的微信...
【标题】"Java仿微信全栈 高性能后台+移动客户端.zip" 提示我们这是一个关于使用Java技术栈来模仿微信功能的项目,其中包括高性能的后端服务和移动客户端的实现。这个项目很可能是基于Spring Boot框架构建的,因为...
在IT行业中,模仿朋友圈图片上传是一项常见的用户界面(UI)设计任务,主要目的是提供与社交媒体应用类似的功能,让用户能够方便地分享自己的照片。这个过程涉及到前端开发、图像处理、用户体验等多个方面。以下将...
这个DEMO旨在模仿微信小程序的主要功能和界面,为开发者提供了一个学习和参考的实例。通过分析这个DEMO,我们可以深入理解小程序的开发流程、架构设计以及微信小程序API的使用。 首先,微信小程序是一种轻量级的...
【标题】"android仿开心网源代码.zip"所代表的是一个Android应用开发项目,目标是模仿知名社交网络“开心网”的功能和界面设计。这个压缩包包含了一系列的资源和代码,帮助开发者理解如何在Android平台上构建类似的...
此外,游戏的得分系统、生命周期管理、游戏状态的保存与恢复,以及网络功能(如排行榜、邀请好友等)都是游戏开发中的常见模块。Java的集合框架(如ArrayList、HashMap)和IO流可以方便地处理这些问题。 总之,"打...