UI相关问题

ListView相关

ListView的setOnItemClickListener无效

问题:使用listview的时候遇到了设置item监听事件的时候在没有回调onItemClick 方法的问题

我的情况是在item中有一个Button按钮,所以不会回调。

解决:

法1. 在checkbox、button对应的view处加

1
2
3
android:focusable=”false”
android:clickable=”false”
android:focusableInTouchMode=”false”

法2. 在item最外层添加属性

1
android:descendantFocusability=”blocksDescendants”

原因:当listview中包含button,checkbox等控件的时候,android会默认将focus给了这些控件,也就是说listview的item根本就获取不到focus,所以导致onitemclick时间不能触发

ArrayIndexOutOfBoundsException with custom Android Adapter for multiple views in ListView

listView有多种布局,可能是getItemViewType() >= getViewTypeCount() 导致的(检查getViewTypeCount()的值是不是写死了)

ListView滑动到标题栏、导航栏上

现象:出现滑动ListView滑动到标题栏上、导航栏上。点击标题栏上tab(多tab页面)此tab会刷新成原来没有被覆盖的样子。

寻找问题的经历的步骤:

1、猜测是 PagerSlidingTabStrip(PagerSlidingTabStrip+Viewpager+Fragment)导致的,故替换成TabLlayout+ViewPager+Fragment来实现。结果还是不行

ListView滑动到标题栏、导航栏上1.png

2、替换Activity、Adapter,只留item布局不一样,发现问题依然存在。所以定位问题是出在item布局上。查看了item布局发现有

ListView滑动到标题栏、导航栏上2.png

替换了com.u1city.androidframe.customView.FilletFrameLayout为RelativeLayout发现正常了。但是圆角没有了,所以自定义圆角RelativeLayout,但是问题又出现了。所以定位到问题是圆角导致的。

最终版本:最外层用RelativeLayout,里面的圆角再通过别的方式来实现。

ListView滑动到标题栏、导航栏上3.png

ListView滑动到标题栏、导航栏上4.png

ListView套多个Editext和多个RatingBar错乱问题

解决代码:

1
2
3
4
5
6
7
8
9
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
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
public class ToEvaluateAdapter extends BaseAdapter {

private LayoutInflater inflater;
private List<CommentInfo> list;

public ToEvaluateAdapter(Context context, List<CommentInfo> list) {
this.list = list;
inflater = LayoutInflater.from(context);
}

@Override
public int getCount() {
return list.size();
}

@Override
public Object getItem(int arg0) {
return list == null ? null : list.get(arg0);
}

@Override
public long getItemId(int arg0) {
return arg0;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;

if (convertView == null) {
convertView = inflater.inflate(R.layout.home_toevaluate_listitem, null);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}

final CommentInfo commentInfo = list.get(position);

/*--------------------------------------EditText -begin-----------------------------------------*/
//把CommentInfo与EditText进行绑定
viewHolder.home_toevaluate_content_edt.setTag(commentInfo);

// 清除焦点
viewHolder.home_toevaluate_content_edt.clearFocus();
viewHolder.home_toevaluate_content_edt.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) {
//存储变化
CommentInfo commentInfo = (CommentInfo) viewHolder.home_toevaluate_content_edt.getTag();
commentInfo.setContent(s + "");
}

@Override
public void afterTextChanged(Editable s) {
}
});

//大部分情况下,getview中有if必须有else
if (!TextUtils.isEmpty(commentInfo.getContent())) {
viewHolder.home_toevaluate_content_edt.setText(commentInfo.getContent());
} else {
viewHolder.home_toevaluate_content_edt.setText("");//没有数值时,这句不能省略,否则会导致别的item展示当前的数据
viewHolder.home_toevaluate_content_edt.setHint("说说哪里满意,帮助大家选择");
}
/*--------------------------------------EditText -end-----------------------------------------*/

/*--------------------------------------RatingBar-begin-----------------------------------*/
//方法一: 给RatingBar设置标记
// viewHolder.ratingBar.setTag(position);
//方法二: 把CommentInfo与RatingBar进行绑定
viewHolder.ratingBar.setTag(commentInfo);
// 清除焦点
viewHolder.ratingBar.clearFocus();
//滑动星星的时候
viewHolder.ratingBar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
@Override
public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
//存储变化
// 方法一:获取标记的数据 CommentInfo commentInfo = getCommentInfo((Integer) ratingBar.getTag());
// 方法二:获取标记的数据
CommentInfo commentInfo = (CommentInfo) viewHolder.ratingBar.getTag();
commentInfo.setGrade(rating);//不要在这进行 *2 的操作,否则会导致每次的数值都翻倍,最终使RatingBar充满,只能在展示的时候进行 *2 展示

if (commentInfo.getGrade() == 0) {
viewHolder.home_toevaluate_value_tv.setText("请滑动星星评分");
viewHolder.home_toevaluate_value_tv.setTextColor(Color.BLACK);
} else {
viewHolder.home_toevaluate_value_tv.setText(commentInfo.getGrade() * 2 + "");
viewHolder.home_toevaluate_value_tv.setTextColor(Color.GREEN);
}
}
});

if (commentInfo.getGrade() == 0) {
viewHolder.home_toevaluate_value_tv.setText("请滑动星星评分");
viewHolder.home_toevaluate_value_tv.setTextColor(Color.BLACK);
} else {
viewHolder.home_toevaluate_value_tv.setText(commentInfo.getGrade() * 2 + "");
viewHolder.home_toevaluate_value_tv.setTextColor(Color.GREEN);
}

viewHolder.ratingBar.setRating(commentInfo.getGrade());
/*--------------------------------------RatingBar-end-----------------------------------*/

return convertView;
}

//方法二:用于取出集合中的数据
private CommentInfo getCommentInfo(int position) {
return list.get(position);
}

class ViewHolder {
RatingBar ratingBar;
TextView home_toevaluate_value_tv;
EditText home_toevaluate_content_edt;

public ViewHolder(View convertView) {
ratingBar = (RatingBar) convertView.findViewById(R.id.home_toevaluate_ratingBar);
home_toevaluate_value_tv = (TextView) convertView.findViewById(R.id.home_toevaluate_value_tv);
home_toevaluate_content_edt = (EditText) convertView.findViewById(R.id.home_toevaluate_content_edt);
}
}

//数据对外的接口
public List<CommentInfo> getList() {
return list;
}
}

在ListView历史复用中Edittext数据显示混乱

解决在ListView历史复用中Edittext数据显示混乱

1
2
3
4
5
6
//大部分情况下,getview中有if必须有else
if(!TextUtils.isEmpty(bean.getInput())){
vh.mEditText.setText(bean.getInput());
}else{
vh.mEditText.setText("");
}

自己挖的坑,为空的时候设置了setHintText没有设置setText导致其他item项的EditText也会显示当前item的值

解决在ListView历史复用中Edittext数据显示混乱

ExpandListView

ExpandListView滑动过程中发现显示错位问题

过程中出现错位问题:隐藏区域上划时显示出图片,本应该显示文字。

发现错误原因:

View childView =convertView;

View childView1 =convertView;

1
getGroupView中写法为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
ChildHolder childHolder;
if (groupPosition == 0) {
View childView =convertView;
if (childView == null) {
childView = LayoutInflater.from(context).inflate(R.layout.item_hdly_child1, null);
childHolder = new ChildHolder();
//...
childView.setTag(childHolder);
} else {
childHolder = (ChildHolder) childView.getTag();
}
//...
convertView = childView;
}else {
View childView1 =convertView;
if (childView1 == null){
childHolder = new ChildHolder();
childView1 = LayoutInflater.from(context).inflate(R.layout.item_hdly_child2, null);
//...
childView1.setTag(childHolder);
}else{
childHolder = (ChildHolder) childView1.getTag();
}
//...
convertView = childView1;
}

正确源码:

1
2
3
4
5
6
7
8
9
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
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
165
166
package rongshanghui.tastebychance.com.rongshanghui.zwdt.hdly;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

import rongshanghui.tastebychance.com.rongshanghui.R;
import rongshanghui.tastebychance.com.rongshanghui.util.NoDoubleClickListener;
import rongshanghui.tastebychance.com.rongshanghui.util.PicassoUtils;
import rongshanghui.tastebychance.com.rongshanghui.zwdt.hdly.bean.HDLYBean;

/**
* Created by shenbinghong on 2018/1/16.
*/

public class ExpandListViewAdapter extends BaseExpandableListAdapter {
private Context context;
// private LayoutInflater inflater = null;
private List<HDLYBean> groups;
public ExpandListViewAdapter(Context context, List<HDLYBean> groups) {
// inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.context = context;
this.groups = groups;
}

@Override
public int getGroupCount() {
return groups.size();
}

@Override
public int getChildrenCount(int groupPosition) {
return groups.get(groupPosition).getItems().size();
}

@Override
public Object getGroup(int groupPosition) {
return groups.get(groupPosition);
}

@Override
public Object getChild(int groupPosition, int childPosition) {
return groups.get(groupPosition).getItems().get(childPosition);
}

@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}

@Override
public long getChildId(int groupPosition, int childPosition) {
// return childPosition;
return getCombinedChildId(groupPosition, childPosition);
}

@Override
public boolean hasStableIds() {
return false;
}

@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
GroupHolder groupHolder;
View groupView = convertView;
if (groupView == null) {
groupView = LayoutInflater.from(context).inflate(R.layout.item_hdly_group, null);
groupHolder = new GroupHolder();
groupHolder.nameTv = (TextView) groupView.findViewById(R.id.item_hdly_group_tv);
groupView.setTag(groupHolder);
}else{
groupHolder = (GroupHolder) groupView.getTag();
}

groupHolder.nameTv.setText(groups.get(groupPosition).getName());
return groupView;
}

@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
ChildHolder childHolder;
if (groupPosition == 0) {
View childView = null;
if (childView == null) {
childView = LayoutInflater.from(context).inflate(R.layout.item_hdly_child1, null);
childHolder = new ChildHolder();
childHolder.imgIv = (ImageView) childView.findViewById(R.id.hdly_child1__bg_iv);
childHolder.ckhfTv = (TextView) childView.findViewById(R.id.hdly_child1_ckhf_tv);
childHolder.lyTv = (TextView) childView.findViewById(R.id.hdly_child1_ly_tv);
childHolder.unreadTv = (TextView) childView.findViewById(R.id.unread);
childView.setTag(childHolder);
} else {
childHolder = (ChildHolder) childView.getTag();
}

if (childPosition == 0) {
PicassoUtils.getinstance().loadNormalByPath(context, groups.get(groupPosition).getItems().get(childPosition).getAvator(), childHolder.imgIv);
if (groups.get(groupPosition).getItems().get(childPosition).getHuifuNum() > 0) {
childHolder.unreadTv.setVisibility(View.VISIBLE);
} else {
childHolder.unreadTv.setVisibility(View.INVISIBLE);
}
childHolder.ckhfTv.setOnClickListener(new NoDoubleClickListener() {
@Override
public void onNoDoubleClick(View v) {

}
});
childHolder.lyTv.setOnClickListener(new NoDoubleClickListener() {
@Override
public void onNoDoubleClick(View v) {

}
});
}

convertView = childView;
}else {
View childView1 = null;
if (childView1 == null){
childHolder = new ChildHolder();
childView1 = LayoutInflater.from(context).inflate(R.layout.item_hdly_child2, null);
childHolder.nameTv = (TextView) childView1.findViewById(R.id.hdly_child2_name_tv);
childHolder.timeTv = (TextView) childView1.findViewById(R.id.hdly_child2_time_tv);
childView1.setTag(childHolder);
}else{
childHolder = (ChildHolder) childView1.getTag();
}

if (childHolder.nameTv != null){
childHolder.timeTv.setText(groups.get(groupPosition).getItems().get(childPosition).getTime());
}
if (childHolder.timeTv != null) {
childHolder.nameTv.setText(groups.get(groupPosition).getItems().get(childPosition).getName());
}

convertView = childView1;
}

return convertView;
}

@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// 根据方法名,此处应该表示二级条目是否可以被点击 先返回true
return true;
}

class GroupHolder{
private TextView nameTv;
}

class ChildHolder{
private ImageView imgIv;
private TextView ckhfTv,unreadTv,lyTv;

private TextView nameTv;
private TextView timeTv;
}
}

NestedScrollView相关

问题:NestedScrollView嵌套 RecyclerView,页面载入时总是滑到最底部

原因:由于 NestedScrollView 嵌套 RecyclerView,RecyclerView 占据焦点会导致 NestedScrollView 内容上滑

解决:

方法一:

在根布局设置android:descendantFocusability="blocksDescendants"

其中android:descendantFocusability有三种值:

  • beforeDescendants:viewGroup 会优先其子类控件而获取到焦点
  • afterDescendants:viewGroup 只有当其子类控件不需要获取焦点时才获取焦点
  • blocksDescendants:viewGroup会覆盖子类控件而直接获得焦点

这种方法会造成页面中 EditText 焦点被抢导致无法输入,需要用第二种方法。

方法二:

1
2
android:focusable="true"
android:focusableInTouchMode="true"

方法三:

NestedScrollView顶部第一个控件使用:

1
2
android:focusable="true"
android:focusableInTouchMode="true"

这种方法不太可靠,因为有时可行,有时不可行。

Called attach on a child which is not detached: ViewHolder

问题:java.lang.IllegalArgumentException: Called attach on a child which is not detached: ViewHolder

我是在使用RecyclerView更新了某个item的数据,调用notifyItemChanged()的时候出现的这个问题。具体也没有报是哪一行的问题,根据错误提示,意思是操作的这个viewholder当前不是被绑定的,因为RecyclerView有缓存机制,未在屏幕上显示的item会被暂时回收,即detached。

1、出现这个问题的原因是更新了不在屏幕中显示的item,解决办法是判断要更新的item是不是在屏幕中,判断方法是获取RecyclerView的LayoutManager,前提是RecyclerView设置的LayoutManager是LinearLayoutManager。获取第一个可见位置和最后一个可见位置的position,判断当前要更新的item的position在这个范围内才更新。

1
2
3
4
5
LinearLayoutManager linearManager = (LinearLayoutManager) recyclerView.getLayoutManager();
//最后一个可见view的位置
int mLastVisibleItemPosition = linearManager.findLastVisibleItemPosition();
//第一个可见view的位置
int mFirstVisibleItemPosition = linearManager.findFirstVisibleItemPosition();

2、但是我的列表只有一条数据,并且是在屏幕中显示的,我在notifyItemChanged(0)还是报了这个错,经过仔细研究代码,我发现我的RecyclerView添加了Header,这样position=0的位置其实是header,所以出现了这样的问题。所以更新List中position位置的数据后要更新的Adapter的位置是position+1,改成notifyItemChanged(1)之后问题解决。

spinner相关

问题:自定义的适配

自定义的适配器问题:spinner在xml中需要记住设备background为null 才可以显示出下拉标志

如果打算修改文字离下拉标志的距离可以通过设置在适配器中的padding来设置。因为这里的设置会直接影响默认位置的距离

点9图相关

问题:点9图片导致其上图片显示未全屏问题

问题描述:

在app启动之后出现了启动页,在启动页上方会覆盖一张广告图。而广告图显示异常:只显示在左上角(屏幕2190x1900而广告图大小431x91)

处理过程:

  1. 断点得知是这个广告图所在的ImageView的大小 getWidth()和getMeasureWidth()都是431,尝试在此ImageView前面动态设置大小:用了重新设置setLayoutParam,无效

  2. 比对上一版的apk是正常,尝试从svn上找动到的文件➡️找到了是启动页由原来的png改成点9图。

原因:点9图的左侧上侧有拉伸,而右侧下侧是限制显示区域却没有设置,只设置了左侧和上侧。

解决:右侧、下侧都弄上“黑边”

问题:点9图,出现“Error:Execution failed for task ‘:app:mergeDebugResources’”

排查:

  1. 检查图片是否是通过工具转成点9图的(不是手动改的后缀)
  2. 检查图片后缀名称是否是“.9.png.png”等两个后缀名,要保留一个
  3. 左、上可以分段黑边,右、下只能一条黑边

Popupwindow

Unable to add window

问题:Unable to add window – token null is not valid; is your activity running?

解决:不能在onCreate()中直接调用显示popupwindow

更改成在触发点击事件后才显示

popupwindow的showAsDropDown失效

解决popupwindow的showAsDropDown失效问题

1
2
3
4
5
6
7
8
9
if (Build.VERSION.SDK_INT >= 24){
Rect visibleFrame = new Rect();
view.getGlobalVisibleRect(visibleFrame);
int height = view.getResources().getDisplayMetrics().heightPixels - visibleFrame.bottom;
baseExpandPopWindow.setHeight(height);
baseExpandPopWindow.showAsDropDown(view,0,0);
}else {
baseExpandPopWindow.showAsDropDown(view,0,0);
}

tablayout

tablayout点击显示灰色背景

解决:添加了app:tabBackground="@color/white"

其他

setVisibility无效问题

现象:view.setVisibility(View.INVISIBLE);无效

原因一:对这个view设置了动画,且给此动画加了属性 anim.setFillAfter(true);

解决:

  • 方案一:
1
2
anim.setFillAfter(false);
view.setVisibility(View.INVISIBLE);
  • 方案二:
1
2
view.clearAnimation();
view.setVisibility(View.INVISIBLE);
  • 方案三:
1
view.postdelay延迟100毫秒
  • 方案四:
1
使用runOnUiThread的方式来实现

如果上述方案都不可行,检查Mainifest.xml,去除android:hardwareAccelerated="false"

对于其他原因,在setVisibility隐藏之后加个刷新。view.invalidate()view.postinvalidate()。前面俩无效再试试自身requestLayout()或父容器的requestLayout()来强制页面刷新。

The layout in layout has no declaration in the base layout folder

解决:选择“Invalidata and Restart”重启AS