Post

一些遇到的问题整理

今天看到Xiaoke’s Blog博客中的一些问题整理,发现自己很多也遇到过,就抽时间也整理一下 这部分引自Xiaoke’s Blog

Fragment的状态恢复问题 [20131218]

在FragmentActivity里,如果存在Fragment,系统恢复被销毁的Activity的同时会回复所有FragmentManager里的Fragment列表,然后添加到当前的Activity中,但问题是,Fragment虽然恢复了,状态却没有回复,这些都需要在onCreate或onRestoreInstanceState中手动处理。补充说明:onCreate()和onRestoreInstanceState()都可以用于应用的状态恢复,区别是onRestoreInstanceState()是在onStart()之后调用,可以根据具体情况选择时机。 “Failure Delivering Result ” - onActivityForResult FragmentActivity恢复状态的源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// onCreate()中
if (savedInstanceState != null) {
	Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
	// FragmentManager的restoreAllState会将之前保存
  //的Fragment重新添加到FragmentManager中,并恢复BackStack
	mFragments.restoreAllState(p, nc != null ? nc.fragments : null);
}
//保存状态的源码如下:
/**	
* Save all appropriate fragment state.
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
	super.onSaveInstanceState(outState);
	Parcelable p = mFragments.saveAllState();
	if (p != null) {
    	outState.putParcelable(FRAGMENTS_TAG, p);
	}
}

Google建议onCreate中只在savedInstanceState为null的时候才创建和初始化Fragment,代码如下:

1
2
3
4
5
6
7
8
9
if (savedInstanceState == null) {
	// During initial setup, plug in the details fragment.
	DetailsFragment details = new DetailsFragment();
	details.setArguments(getIntent().getExtras());
	getFragmentManager()
    .beginTransaction()
    .add(android.R.id.content, details)
    .commit();
}

Background和Seletor必须使用真实的Drawable

否则,有些三星和摩托的机子上会没有背景,显示纯黑色,定义在colors.xml里的伪drawble不行,必须是真实的图片drawable或者定义好的shape,

1
2
<color name="mail_published_time_color">#bcbcbc</color>
<drawable name="ab_bg_black">#aa191919</drawable>

在onActivityResult中显示Dialog [20131218]

通过startActivityForResult调用某一个应用等待返回结果,然后在onActivityResult中需要异步处理的同时显示对话框,如果直接在onActivityResult中调用Dialog.show()会报错,因为onActivityResult是在onResume之前,一个类似的问题是,在onSaveInstanceState调用之后也不能进行FragmentTransaction的commit操作,这两个都影响到DialogFragment,正确的做法有两种: * 方法一:在onPostResume显示对话框 * 方法二:在onActivityResult设置一个标志(比如mPendingShowDialog)为true,然后在onResume()的时候检查标志,如果为true就显示对话框,注意:不仅是Dialog,处理Fragment相关的transactions和commit操作都需要考虑这个问题,在onSaveInstanceState调用之后如果需要commit,请替换成commitAllowingStateLoss,如果不允许状态丢失,就需要寻找其它替代方法。

ListView显示 [20131017]

如果ListView设置了MATCH_PARENT但是内容太少又没有撑满空间,ListView会自动缩小至显示内容所需区域,空白空间会显示默认的背景色,在ME525上是灰色块,解决办法是在主题里加上:

1
<item name="android:overScrollFooter">@android:color/transparent</item>

或者在布局里使用

1
android:overScrollFooter="@android:color/transparent"

,background-color-listview

Drawable填充问题 [20131017]

如果solid不设置颜色的话,那么就有可能存在一个默认的色值

1
2
3
4
5
6
7
8
9
10
11
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
   <!--内部用透明色填充-->
    <solid
            android:color="@color/transparent"/>
    <stroke
            android:width="1dp"
            android:color="@color/soft_white"/>
    <corners
            android:radius="1dp"/>
</shape>

WebView的换行问题 [20131218]

4.4开始,webview不会自动断行,需要在html里处理,代码里也可以这样处理:

1
2
3
settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING);
//但是很多网页这样不解决问题,还需要在Html里处理:
<pre style="word-wrap: break-word; white-space: pre-wrap;">

使用拨号键盘的SecretCode功能

这个是我一个不知道,以后试试,Android的拨号键盘有一些特殊的定义键,可以启动自定义的Intent,Create a secret doorway to your app用法:

1
2
3
4
5
6
<receiver android:name=".receiver.DiagnoserReceiver">
    <intent-filter>
        <action android:name="android.provider.Telephony.SECRET_CODE"/>
        <data android:scheme="android_secret_code" android:host="111222"/>
    </intent-filter>
</receiver>
1
2
3
4
5
6
7
8
9
10
public class DiagnoserReceiver extends BroadcastReceiver {
	public void onReceive(Context context, Intent intent) {
        if ("android.provider.Telephony.SECRET_CODE".equals(intent.getAction())) {
            Intent i = new Intent(Intent.ACTION_MAIN);
            i.setClass(context, Diagnoser.class);
            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(i);
        }
	 }
}

How to import existing GIT repository into another?

I’ve tried several methods now and this is the one I prefer. It is from github’s “Subtree Merge” help article and it results in unmodified history of the subtree plus one merge commit to move the merged repository to the subdirectory, which is just what you want.

1
2
3
4
5
6
7
git remote add rack_remote git@github.com:schacon/rack.git
git fetch rack_remote
git merge -s ours --no-commit rack_remote/master
git read-tree --prefix=rack/ -u rack_remote/master
git commit -m "Imported rack as a subtree."
#You can track upstream changes like so:
git pull -s subtree rack_remote master

Git figures out on its own where the roots are before doing the merge, so you don’t need to specify the prefix on subsequent merges.I had previously recommended the ]Pro Git Subtree Merging method but recant that recommendation since as it turns out their method skips the merge -s ours step so the read-tree is effectively no different than copying the files with cp.. That’s obviously no good.

Ripple effect on Android Lollipop CardView

The ripple effect was omitted in the appcompat support library which is what you’re using. If you want to see the ripple use the Android L version and test it on an Android L device. Per the AppCompat v7 site:”Why are there no ripples on pre-Lollipop? A lot of what allows RippleDrawable to run smoothly is Android 5.0’s new RenderThread. To optimize for performance on previous versions of Android, we’ve left RippleDrawable out for now.”

1
2
3
4
5
6
7
<android.support.v7.widget.CardView 
	android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:foreground="?android:attr/selectableItemBackground"
    android:clickable="true">
    ...

Mac OS X下的移动光标和文字编辑快捷键

苹果的快捷键文档

  • 移动光标快捷键
    • Control-F 光标前进一个字符,相当于右键(F = Forward)
    • Control-B 光标后退一个字符,相当于左键(B = Backward)
    • Control-P 上移一行,相当于上键(P = Previous)
    • Control-N 下移一行,相当于下键(N = Next)
    • Control-A 移动到一行的开头(A = Ahead)
    • Control-E 移动到一行的结尾(E = End)
  • 文字操作快捷键
    • Control-H 删除光标前面的字符
    • Control-D 删除光标后面的字符
    • Control-K 删除从光标开始,到一行结尾的所有字符
    • Control-Shift-A 选中从光标开始,到一行开头的所有文字
    • Control-Shift-E 选中从光标开始,到一行结尾的所有文字

切换 git

因为 Xcode 也 自带了 git,以前也装过其他的版本的 git,现在打算都使用brew cask来管理,所以需要切换一下,过程中比较纠结一下

1
2
3
4
5
6
//change into the Xcode directory:
$ cd /Applications/Xcode.app/Contents/Developer/usr/bin
//rename the Xcode git like this:
$ sudo mv ./git ./git-xcode-usr-bin
//link my own git which is installed through homebrew:
$ sudo ln -s /usr/local/bin/git ./git
This post is licensed under CC BY 4.0 by the author.