Android问题集锦

目录
  1. 1. android:screenOrientation属性
  2. 2. 阻止activity启动后editview自动获得焦点
  3. 3. editText 取消下划线等自带样式
  4. 4. android中为何第三方开源库生成的jar包不能直接放入libs中用?
  5. 5. 去除ViewPagerIndicator圆点的动态效果
  6. 6. android:onClick=”xxx”
  7. 7. 编译出错 ERROR: 9-patch image xxx.9.png malformed
  8. 8. TextView 如何居中
  9. 9. 使用代码为textview设置drawableLeft
  10. 10. scrollView的fillviewport
  11. 11. android:ellipsize的使用
  12. 12. Android应用开发之图片热点效果实现
  13. 13. notifyDataSetInvalidated()和notifyDataSetChanged()区别?
  14. 14. android6.0 蓝牙搜索不到设备
  15. 15. LinearLayout水平布局,最后一个子view靠右对齐
  16. 16. 重新从数据库new了新的list之后,notifyDataSetChanged()无效
  17. 17. Fragment无法使用android:onClick属性
  18. 18. 让edittext失去焦点
  19. 19. RelativeLayout 中的 layout_below失效
  20. 20. listview默认选中某一项
  21. 21. Listview/RecyclerView复用item导致的数据错位

android:screenOrientation属性

在开发android的应用中,有时候需要限制横竖屏切换。只需要在AndroidManifest.xml文件中加入android:screenOrientation属性限制。
android:screenOrientation="landscape"是限制此页面横屏显示
android:screenOrientation="portrait"是限制此页面数竖屏显示


阻止activity启动后editview自动获得焦点

在EditView的父级Layout上添加属性:
android:focusable="true"
android:focusableInTouchMode="true"


editText 取消下划线等自带样式

android:background="@null"


android中为何第三方开源库生成的jar包不能直接放入libs中用?

这是因为第三方库中可能含有”res资源”(如:layout、drawable等),而jar包是不会携带这些东西的。如果第三方开源库未使用”资源”,直接生成jar包使用是没有问题!
比如”pulltorefresh开源项目”(搜包名com.chrisbanes.pulltorefresh即可搜到),含drawable资源,但是打包成jar包后只有java字节码!


去除ViewPagerIndicator圆点的动态效果

com.viewpagerindicator.CirclePageIndicator中添加属性:app:snap="true"


android:onClick=”xxx”

一般监听OnClickListener事件,我们都是通过button.setOClickLisener....这样的方式来实现。
这段时间看各大开放平台的demo,发现其实可以在xml中定义好方法名称,在Activity中实现该方法就可以了。

1
2
3
4
5
6
7
8
9
10
<Button
android:layout_width="70dp"
android:layout_height="wrap_content"
android:onClick="share_activity_back"
android:text="返回" />

public void share_activity_back(View v) {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
}

在Activity中直接实现该方法即可,也无需定义button,实例化它,跟原先一比方便了很多。


编译出错 ERROR: 9-patch image xxx.9.png malformed

如果在Android项目中使用Nine Patch资源,时候可能出现比如ERROR: 9-patch image xxx.9.png malformed.
或 No marked region found along edge.
以及 Found along top edge.的错误

主要是因为该图片没有四周的定位像素,至少必须在左边和上方定位像素。


TextView 如何居中

Android TextView 的居中例子 android:gravity="center",必须写上这个属性,文本才能居中, 用android:layout_gravity="center"不行;
android:gravity和android:layout_gravity的区别:android:gravity用于设置View组件(比如TextView )的对齐方式,而android:layout_gravity用于设置Container组件(比如LinearLayout)的对齐方式。


使用代码为textview设置drawableLeft

1.在XML中使用android:drawableLeft="@drawable/icon"

2.代码中动态变化

1
2
3
4
Drawable drawable= getResources().getDrawable(R.drawable.drawable);
// 这一步必须要做,否则不会显示.
drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
myTextview.setCompoundDrawables(drawable,null,null,null);

也或参考另一个函数
myTextview.setCompoundDrawablesWithIntrinsicBounds (Drawable left, Drawable top, Drawable right, Drawable bottom);


scrollView的fillviewport

android:fillViewport="true"
当你想让一个高度值不足scrollview的子控件fillparent的时候,单独的定义android:layout_height="fill_parent"是不起作用的,必须加上fillviewport属性,当子控件的高度值大于scrollview的高度时,这个标签就没有任何意义了。


android:ellipsize的使用

EidtText和textview中内容过长的话自动换行,使用android:ellipsize与android:singleine可以解决,使只有一行。

EditText不支持marquee

用法如下:

在xml中

1
2
3
4
5
android:ellipsize = "end"    省略号在结尾
android:ellipsize = "start"   省略号在开头
android:ellipsize = "middle" 省略号在中间
android:ellipsize = "marquee" 跑马灯
android:singleline = "true"

当然也可以用代码语句

1
2
3
4
5
tv.setEllipsize(TextUtils.TruncateAt.valueOf("END"));
tv.setEllipsize(TextUtils.TruncateAt.valueOf("START"));
tv.setEllipsize(TextUtils.TruncateAt.valueOf("MIDDLE"));
tv.setEllipsize(TextUtils.TruncateAt.valueOf("MARQUEE"));
tv.setSingleLine(true);

Android应用开发之图片热点效果实现

今天要开发的应用需要一个效果是:背景图片上添加一些热点,然后点击热点就执行对应的动作。查了查没有专用的组件,最后用了一个小trick实现的,特地拿来记录一下。

实现步骤:
1.用ImageView添加图片;
2.在热点处安放Button;
3.在程序中(或直接在布局文件中)修改Button的属性: button.getBackground().setAlpha(0), 将button的背景设置为全透明;
4.在button.onClickListener中添加触发热点后的自定义动作,done.
最后可能还要调整下布局之类的,但是功能方面就没问题了。


notifyDataSetInvalidated()和notifyDataSetChanged()区别?

notifyDataSetChanged方法通过一个外部的方法控制如果适配器的内容改变时需要强制调用getView来刷新每个Item的内容。

public void notifyDataSetChanged ()
该方法内部实现了在每个观察者上面调用onChanged事件。每当发现数据集有改变的情况,或者读取到数据的新状态时,就会调用此方法。

public void notifyDataSetInvalidated ()
该方法内部实现了在每个观察者上面调用onInvalidated事件。每当发现数据集监控有改变的情况,比如该数据集不再有效,就会调用此方法。

notifyDataSetInvalidated(),会重绘控件(还原到初始状态)
notifyDataSetChanged(),重绘当前可见区域


android6.0 蓝牙搜索不到设备

发现:使用使用蓝牙协议2.0的App,搜索不到任何蓝牙设备,使用BLE的正常。

BluetoothAdapter.getDefaultAdapter().startDiscovery()不起作用

百度,Google后,发现别人也遇到了同样的问题。

最后查资料,搞了一个早上,最后找到了答案:链接:https://developer.Android.com/about/versions/marshmallow/android-6.0-changes.html

android6.0更新了权限模型。

在原来的App的AndroidManifest.xml中加入权限声明即可。亲测有效。

PS:还是要看官方的文档,其他文章大部分不靠谱。

1
2
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />  
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

LinearLayout水平布局,最后一个子view靠右对齐

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:orientation="horizontal" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="验证码:" />

<EditText
android:id="@+id/yzm_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" //重点
/>

<TextView
android:id="@+id/yzm"
android:layout_width="100dp"
android:layout_height="30dp" />
</LinearLayout>

重新从数据库new了新的list之后,notifyDataSetChanged()无效

1
2
3
diaryList.clear(); // diaryList是adapter的属性
diaryList.addAll(diarys); // diarys是从数据库获取的新的list
adapter.notifyDataSetChanged(); //不使用addAll()的话,notifyDataSetChanged()无效

Fragment无法使用android:onClick属性

在布局文件中同样可以给Button绑定Click时间的响应函数。如:

1
2
3
4
5
6
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="OnClick"
android:text="Button" />

然后在Activity里面实现OnClick()函数:

1
2
3
public void OnClick(View v) {
System.out.println("Click");
}

真的很方便,不是吗?但是你千万不要高兴的太早,因为正有一个很大的坑在等着你!

问题就出在Fragment身上,前面说了它不是布局器,所以它不具备渲染视图的能力,它管理的布局器最终要加载到一个ViewGroup对象内,由ViewGroup对象来渲染。而视图树并不知道每一个子控件来源于哪里,这就导致了一个结果:不管是在什么地方定义的onClick属性,都必须在包含该Button的Activity中去寻找OnClick()方法。

可能有人说,API中对onClick早有说明:设置点击时从上下文中调用指定的方法,只是你不知道而已。事实确实是这样,但是我是一个追根溯源的人,如果我没有遇到这么多的问题,我可能只知道应该怎么做,却不知道为何应该这样做。

抛开onClick属性,我们仍然可以使用代码的方式实现对Click的事件响应,但是毕竟——不优雅——了。

曾经我想到了一种办法——使用约定:让使用该Fragment的Activity实现一个包含所有OnClick()函数的接口。


让edittext失去焦点

EditText初始化时候失去焦点:只需要在布局文件中设置属性

android:focusable="false"

也可以在代码中由开发者根据需求设置一定的条件,当条件满足后,动态的设置EditText失去焦点。

示例代码:

1
2
3
EditText et = (EditText) findViewById(R.id.et);
et.clearFocus();
et.setFocusable(false);

这种控制EditText的操作是Android程序中不经常用到的。多出现于EditText的输入监听回调方法中。


RelativeLayout 中的 layout_below失效

在Relativelayout 未设置具体高度的情况下,作为参照物的兄弟元素使用相对属性:android:layout_centerInParent="true",后者layout_below失效。

解决办法:
给Relativelayout设置具体高度,或者取消相对属性设置。


listview默认选中某一项

使用ListView.performItemClick(view, position, id),这个方法是为了模拟用户点击而存在的。
realListView.performItemClick(realListView.getChildAt(position), position, realListView.getItemIdAtPosition(position));
注意RecyclerView没有performItemClick这个方法,如果想在RecyclerView中默认选中某一项,使用:
RecyclerView.getChildAt(position).performClick();


Listview/RecyclerView复用item导致的数据错位

数据渲染到列表,经常在Adapter中会包含部分内容是否显示的判断,比如status=1时候则显示【已付费】。
Adapter中的代码如下:

1
2
3
if(status ==1){
textView.setVisible(VISIBLE);
}

看着好像是没问题,但是因为Listview/RecyclerView会复用item,所以有的item,虽然status=0,但是仍然会显示【已付费】。
解决方法就是在做判断的时候,加上else就好了:

1
2
3
4
5
if(status ==1){
textView.setVisible(VISIBLE);
}else{
textView.setVisible(GONE);
}