我有一个带有数组适配器的listview,它显示了不同的视图来表示项目的不同属性。同一项目多次添加到列表中,以创建这些视图。
由于这些观点是独一无二的,我创建了一个枚举来管理每个观点的通货膨胀。
问题,从maxDistanceTv
调用setMaxDistanceText()
后,onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
的文字未更新。
我尝试使用new Handler().post(new Runnable()...)
,runOnUiThread(new Runnable()...)
,.invalidate()
,.postInvalidate()
,但没有一个有效。
调试时,我可以看到maxDistanceTv
的文字(mText
)更新为新的正确值,但该更改未反映在用户界面中。
以下是枚举的相关部分:
public enum BleDeviceProperties implements IDevicePropertiesInflater {
ALERT_DISTANCE(R.layout.property_alert_distance, new IDevicePropertiesInflater() {
private TextView maxDistanceTv;
private SeekBar maxDistanceSb;
private BleDeviceInfo info;
private View view;
private void setMaxDistanceText(){
maxDistanceTv = (TextView) view.findViewById(R.id.max_distance_tv);
maxDistanceTv.setText(String.valueOf(info.getThreshold()));
}
private void setMaxDistanceProgress(){
maxDistanceSb = (SeekBar) view.findViewById(R.id.max_distance_sb);
maxDistanceSb.setMax(BleDeviceInfo.STEPS);
maxDistanceSb.setProgress(info.getThresholdNormalized());
maxDistanceSb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
info.setThresholdNormailized(progress);
BluetoothLeServiceMessanger.getInstance().sendNewRssiThresholdSet(info.getThreshold());
setMaxDistanceText();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
@Override
public void inflateData(View view, BleDeviceInfo info) {
this.info = info;
this.view = view;
setMaxDistanceText();
setMaxDistanceProgress();
}
}),
...
private int viewId;
private IDevicePropertiesInflater propertiesInflater;
@Override
public void inflateData(View view, BleDeviceInfo info) {
if(propertiesInflater != null){
propertiesInflater.inflateData(view,info);
}
}
public int getViewId() {
return viewId;
}
BleDeviceProperties(int viewId, IDevicePropertiesInflater propertiesInflater) {
this.viewId = viewId;
this.propertiesInflater = propertiesInflater;
}
}
public interface IDevicePropertiesInflater {
void inflateData(View view,BleDeviceInfo info);
}
public class DevicePropertiesAdapter extends ArrayAdapter<BleDeviceInfo>{
private static final int VIEW_TYPE_COUNT = 4;
private Activity activity;
public void setInfo(BleDeviceInfo info){
clear();
for(int i=0;i<VIEW_TYPE_COUNT;i++){
add(info);
}
notifyDataSetChanged();
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public int getViewTypeCount() {
return VIEW_TYPE_COUNT;
}
public DevicePropertiesAdapter(Activity activity, int resource) {
super(activity, resource);
this.activity = activity;
}
@Override
public View getView(int position, View view, final ViewGroup parent) {
View rowView;
if(view == null) {
LayoutInflater inflater = activity.getLayoutInflater();
rowView = inflater.inflate(BleDeviceProperties.values()[position].getViewId(), null);
}else{
rowView = view;
}
BleDeviceProperties.values()[position].inflateData(rowView, getItem(position));
return rowView;
}
}
答案 0 :(得分:1)
最终,我尝试了:
,而不是从setMaxDistanceText()
拨打onProgressChanged
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
info.setThresholdNormailized(progress);
BluetoothLeServiceMessanger.getInstance().sendNewRssiThresholdSet(info.getThreshold());
//setMaxDistanceText();
maxDistanceTv = (TextView) ((ViewGroup)seekBar.getParent()).findViewById(R.id.max_distance_tv);
maxDistanceTv.setText(String.valueOf(info.getThreshold()));
}
它有效。我仍然不知道为什么TextView不会使用原始问题中的代码进行更新。
修改强> 阅读此here:
永远不要将listview的layout_height和layout_width设置为 wrap_content as getView()将强制你的适配器获取一些孩子 用于测量要在列表视图中绘制的视图的高度,并且可以 导致一些意想不到的行为,如返回convertview甚至 list不滚动。总是使用match_parent或固定宽度/高度。
将layout_height
和layout_width
的值更改为match_parent
后,原始代码才能正常运作。