sqlite3.25.0源码_Android6.0源码修改Contacts应用

一、Contacts应用的主界面和联系人详情界面增加顶部菜单添加退出按钮

通过Hierarchy View 工具可以发现

主界面对应的类为 PeopleActivity

联系人详情界面对应的类为 QuickContactActivity

左上角的退出按钮其实很简单,系统actionBar已经帮我们实现了这一功能,只是没有显示出来而已。在onCreate()方法中,在setContentView()方法之后,添加如下代码即可显示返回的箭头

 ActionBar mActionBar = getActionBar(); if (mActionBar != null) { Log.i(TAG, "getSupportActionBar != null...."); mActionBar.setDisplayHomeAsUpEnabled(true); mActionBar.setHomeButtonEnabled(true); }

接下来在onOptionsItemSelected()中监听返回按钮的事件即可

@Overridepublic boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: { finish(); } return true; } ....}
format,png

图1 左上角返回退出功能

二、第三方app拉起主界面时直接显示模糊查询对应的联系人列表

简单分析一下,模糊查询需要对应的查询联系人名称,可以通过intent传递参数,这里定义为String类型,当传递参数不为null时,模拟手动点击搜索框对应的逻辑。如下在 PeopleActivity 的 onCreate()方法中增加获取参数的代码

final String queryString = getIntent().getStringExtra("queryString"); if (!TextUtils.isEmpty(queryString)) { new Handler().postDelayed(new Runnable() { @Override public void run() { showQueryTextFragment(queryString); } }, 100);//让搜索逻辑延迟100ms执行 }

通过测试发现,不加延迟触发搜索框对应的逻辑并不会显示模糊查询结果界面。接下来我们分析点击搜索框对应的逻辑代码,找到搜索框对应的控件id,menu_search, 回到刚刚的菜单监听方法 onOptionsItemSelected()中

@Overridepublic boolean onOptionsItemSelected(MenuItem item) { ... switch (item.getItemId()) { case R.id.menu_search: { onSearchRequested(); return true; } } ...}@Overridepublic boolean onSearchRequested() { // Search key pressed. Log.d(TAG, "[onSearchRequested]"); //不在搜索模式下,也就是没有点击过搜索框 if (!mActionBarAdapter.isSelectionMode()) { //获取焦点,弹出键盘 mActionBarAdapter.setSearchMode(true); } return true;}

从上面不难看出最终调用 mActionBarAdapter 的方法,我们接着跟进去

源码位置 packages/apps/Contacts/src/com/android/contacts/activities/ActionBarAdapter.java

public void setSearchMode(boolean flag) { if (mSearchMode != flag) { mSearchMode = flag; update(false /* skipAnimation */); if (mSearchView == null) { return; } if (mSearchMode) { mSearchView.setEnabled(true); setFocusOnSearchView(); } else { // Disable search view, so that it doesn't keep the IME visible. mSearchView.setEnabled(false); } setQueryString(null); } else if (flag) { // Everything is already set up. Still make sure the keyboard is up //需要注释此处,不然多次调用并退出再次拉起容易出现键盘弹出的情况 //if (mSearchView != null) setFocusOnSearchView(); }}public void setFocusOnSearchView() { //mSearchView获取焦点(先获取焦点才能弹出键盘) mSearchView.requestFocus(); //弹出键盘 showInputMethod(mSearchView); // Workaround for the "IME not popping up" issue.}private void showInputMethod(View view) { final InputMethodManager imm = (InputMethodManager) mActivity.getSystemService( Context.INPUT_METHOD_SERVICE); if (imm != null) { imm.showSoftInput(view, 0); }}

看到这里我们可以猜想到 mSearchView 肯定设置了文字改变监听,继续查找 addTextChangedListener

...mSearchView.setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);mSearchView.addTextChangedListener(new SearchTextWatcher());...private class SearchTextWatcher implements TextWatcher { @Override public void onTextChanged(CharSequence queryString, int start, int before, int count) { if (queryString.equals(mQueryString)) { return; } //当前输入的模糊查询的名称 mQueryString = queryString.toString(); if (!mSearchMode) { if (!TextUtils.isEmpty(queryString)) { setSearchMode(true); } } else if (mListener != null) { //回调通知 PeopleActivity 改变界面 mListener.onAction(Action.CHANGE_SEARCH_QUERY); } mClearSearchView.setVisibility( TextUtils.isEmpty(queryString) ? View.GONE : View.VISIBLE); } @Override public void afterTextChanged(Editable s) {} @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}}

回到 PeopleActivity 中找到监听 Action.CHANGE_SEARCH_QUERY 的代码如下

 @Overridepublic void onAction(int action) { Log.d(TAG,"[onAction]action = " + action); /// M: [vcs] @{ if (mVcsController != null) { mVcsController.onActionVcs(action); } /// @} switch (action) { ... case ActionBarAdapter.Listener.Action.CHANGE_SEARCH_QUERY: //获取当前输入的模糊查询姓名 final String queryString = mActionBarAdapter.getQueryString(); //显示对应的fragment setQueryTextToFragment(queryString); updateDebugOptionsVisibility( ENABLE_DEBUG_OPTIONS_HIDDEN_CODE.equals(queryString)); break; default: throw new IllegalStateException("Unkonwn ActionBarAdapter action: " + action); }}

到此,搜索框模糊查询对应的逻辑就分析完了,那么我们就模拟调用对应的逻辑就ok了,再来把整体流程捋一遍,

点击搜索框->获取焦点->弹出键盘->输入姓名->收到文字内容改变的监听->将输入的内容回调给 PeopleActivity->收到回调显示对应的结果Fragment

好了,通过调用EditText.setText()方法也能触发文字内容改变的监听,前提是要先获取焦点,那么我们的 showQueryTextFragment() 实现如下

private void showQueryTextFragment(String queryString){ Log.d(TAG, "[showQueryTextFragment]"); if (!mActionBarAdapter.isSelectionMode()) { Log.e(TAG, "[queryString==]"+queryString); mActionBarAdapter.setSearchMode(true); mActionBarAdapter.setQueryString(queryString); }}
format,png

图2 第三方app拉起主界面显示对应的联系人

三、第三方app拉起联系人详情界面只滑动到一半显示的问题

format,png

图3 拉起只显示一半

format,png

图4 拉起完全显示

首先从系统的联系人列表界面点击进入详情界面是能完整显示的,所以猜想应该是传递的参数不太一样。所以还是从onCreate()方法看下来

public class QuickContactActivity extends ContactsActivity { /** * QuickContacts immediately takes up the full screen. All possible information is shown. * This value for {@link android.provider.ContactsContract.QuickContact#EXTRA_MODE} * should only be used by the Contacts app. */ public static final int MODE_FULLY_EXPANDED = 4; //看上面的注释就知道了肯定是跟这个变量有关系, 立刻显示全屏,应当只用于 联系人 app 使用 @Override protected void onCreate(Bundle savedInstanceState) { Trace.beginSection("onCreate()"); super.onCreate(savedInstanceState); if (RequestPermissionsActivity.startPermissionActivity(this)) { return; } getWindow().setStatusBarColor(Color.TRANSPARENT); //处理Intent传递的参数 processIntent(getIntent()); ..... //Scroller初始化,传递滚动模式 mScroller.initialize(mMultiShrinkScrollerListener, mExtraMode == MODE_FULLY_EXPANDED); // mScroller needs to perform asynchronous measurements after initalize(), therefore // we can't mark this as GONE. mScroller.setVisibility(View.INVISIBLE); ... } private void processIntent(Intent intent) { ... //获取传递的EXTRA_MODE,不传默认为large,查看api对应的int值为3,MODE_FULLY_EXPANDED为4, 所以不传递参数或者参数对应值不为4就只显示半屏 mExtraMode = getIntent().getIntExtra(QuickContact.EXTRA_MODE, QuickContact.MODE_LARGE);  ... }}

通过上面的分析 intent需要传递 QuickContact.EXTRA_MODE 参数, 当你点进去 QuickContact中发现并没有对应4的变量(猜想应该是留了一手不让第三方app直接全屏显示)

正确的打开姿势

private void gotoContact(){ Uri personUri = ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 1); Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(personUri); //这句比较关键 intent.putExtra(ContactsContract.QuickContact.EXTRA_MODE, 4); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent);}

总结

1、话说当把navigationBar去掉以后,给每个activity添加返回按钮是个很麻烦的工作,可以借鉴一下苹果的思路,直接在屏幕(Window)中添加一个悬浮的按钮处理返回点击事件。

2、源码没那么可怕,干起来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值