Android 每 2 秒更新 UI
Android update UI every 2 seconds
我已经搜索并尝试了将近一天的解决方案,但没有任何效果,所以我决定 post 我的代码在这里,希望有人能给我一些帮助,谢谢!
我有一个扩展 ListFragment 的片段。
列表有四项;下面三个,我只是在我的私有ListAdapter class
中的getView()
方法中设置了他们的图片和文字。对于第一个,我想不断地改变它的画面。我有一个位图数组 promotion_image_array
,其中包含三个位图,我将用作第一项的源。以下是我的getView()
的代码和我现在得到的截图:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
View myView = convertView;
System.out.println("in getView");
if (myView == null) {
myView = inflater.inflate(R.layout.home_category_item, null);
holder = new ViewHolder();
holder.item_image= (ImageView)myView.findViewById(R.id.item_image);
holder.res_name = (TextView)myView.findViewById(R.id.res_name);
if(position == 0){
holder.res_name.setVisibility(View.GONE);
promotion_image_view = holder.item_image;
System.out.println("position == 0");
}
else if(position == 1) {
holder.res_name.setText("Food");
holder.item_image.setBackgroundResource(R.drawable.restaurant_icon);
System.out.println("position == 1");
}
else if(position == 2) {
holder.res_name.setText("Shop");
holder.item_image.setBackgroundResource(R.drawable.shop_icon);
System.out.println("position == 2");
}
else if(position == 3) {
holder.res_name.setText("Groupon");
holder.item_image.setBackgroundResource(R.drawable.groupon_icon);
System.out.println("position == 3");
}
myView.setTag(holder);
}
else {
// View recycled, no need to inflate
holder = (ViewHolder) myView.getTag();
}
return myView;
}
}
我尝试使用处理程序和 运行nable 在片段的 onCreate() 方法中持续更新第一项的图像。我有一个静态变量 promotion_image_view,我在片段的顶部声明了它,我使用这行代码在我的 getView() 方法中获取第一个项目的实际 ImageView:(来自上面的代码片段)
promotion_image_view = holder.item_image;
然后我尝试在我的运行nable的运行()方法中设置promotion_image_view的背景,下面是我的运行nable的代码和onCreate() 中的处理程序:
counter = 0;
mHandler = new MyHandler(this);
runnable = new Runnable() {
@Override
public void run() {
mHandler.postDelayed(runnable,3000);
// Repeatedly display three promotion images
Bitmap[] promotion_image_array = my_global_variables.city_config_object.config_promotion_image_array;
BitmapDrawable ob = new BitmapDrawable(my_resources, promotion_image_array[counter]);
if(promotion_image_view != null) {
promotion_image_view.setBackground(ob);
System.out.println("promotion_image_view != null");
}
System.out.format("in run: counter = %d%n", counter);
counter++;
if(counter == 3) counter = 0;
}
};
runnable.run();
promotion_image_view != null
和
in run: counter = %d%n
,计数器
正确打印(以恒定速率连续打印)并且计数器的值也正确。(0,1,2,0,1,2,0 .....)。但是画面一点变化都没有
非常感谢任何帮助,谢谢!!
********************************* 阅读一些答案后 --- 第一次编辑 ***** ***************************
感谢回答的人,我尝试了notifyDataSetChanged()方法,还是不行;图像未更改,但打印输出看起来正确。
修改后的代码如下:
getView() 方法:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
View myView = convertView;
if (myView == null) {
myView = inflater.inflate(R.layout.home_category_item, null);
holder = new ViewHolder();
holder.item_image= (ImageView)myView.findViewById(R.id.item_image);
holder.res_name = (TextView)myView.findViewById(R.id.res_name);
if(position == 0){
holder.res_name.setVisibility(View.GONE);
Bitmap[] promotion_image_array = my_global_variables.city_config_object.config_promotion_image_array;
BitmapDrawable ob = new BitmapDrawable(my_resources, promotion_image_array[counter]);
holder.item_image.setBackground(ob);
System.out.format("in run: counter = %d%n", counter);
counter++;
if(counter == 3) counter = 0;
System.out.println("in getView: position == 0");
}
else if(position == 1) {
holder.res_name.setText("Food");
holder.item_image.setBackgroundResource(R.drawable.restaurant_icon);
System.out.println("position == 1");
}
else if(position == 2) {
holder.res_name.setText("Shop");
holder.item_image.setBackgroundResource(R.drawable.shop_icon);
System.out.println("position == 2");
}
else if(position == 3) {
holder.res_name.setText("Groupon");
holder.item_image.setBackgroundResource(R.drawable.groupon_icon);
System.out.println("position == 3");
}
myView.setTag(holder);
}
else {
// View recycled, no need to inflate
holder = (ViewHolder) myView.getTag();
}
return myView;
}
}
handler 和 运行nable:
counter = 0;
mHandler = new MyHandler(this);
runnable = new Runnable() {
@Override
public void run() {
mHandler.postDelayed(runnable, 3000);
adapter.notifyDataSetChanged();
}
};
runnable.run();
下面是我认为正确的打印输出:
I/System.out﹕ in 运行: counter = 0
I/System.out﹕ in getView: position == 0
I/System.out﹕位置== 1
I/System.out﹕位置==2
I/System.out:位置== 3
I/System.out﹕ in 运行: counter = 1
I/System.out﹕ in getView: position == 0
I/System.out﹕ in 运行: counter = 2
I/System.out﹕ in getView: position == 0
I/System.out﹕ in 运行: counter = 0
I/System.out﹕ in getView: position == 0
I/System.out﹕ in 运行: counter = 1
I/System.out﹕ in getView: position == 0
I/System.out﹕ in 运行: counter = 2
I/System.out﹕ in getView: position == 0
I/System.out﹕ in 运行: counter = 0
I/System.out﹕ in getView: position == 0
使用静态变量 "promotion_image_view " 不是一个好主意。
因为,android 列表视图回收它自己的列表。见下文:
相反,使用图像幻灯片库怎么样?
https://github.com/daimajia/AndroidImageSlider
或,你可以更改你的真实数据(不是getView中生成的数据)然后像这样调用notifyDataSetChanged()方法.
runOnUiThread(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
});
编辑1:
重点是:if (myView == null)
您正在更新您的 imageView,仅当它 为 null 时。
那么,将该代码移到空检查代码之外怎么样?
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
View myView = convertView;
if (myView == null) {
myView = inflater.inflate(R.layout.home_category_item, null);
holder = new ViewHolder();
holder.item_image = (ImageView) myView.findViewById(R.id.item_image);
holder.res_name = (TextView) myView.findViewById(R.id.res_name);
} else {
// View recycled, no need to inflate
holder = (ViewHolder) myView.getTag();
}
if (position == 0) {
holder.res_name.setVisibility(View.GONE);
Bitmap[] promotion_image_array = my_global_variables.city_config_object.config_promotion_image_array;
BitmapDrawable ob = new BitmapDrawable(my_resources, promotion_image_array[counter]);
holder.item_image.setBackground(ob);
System.out.format("in run: counter = %d%n", counter);
System.out.println("in getView: position == 0");
counter = counter++ % 3;
} else if (position == 1) {
holder.res_name.setText("Food");
holder.item_image.setBackgroundResource(R.drawable.restaurant_icon);
System.out.println("position == 1");
} else if (position == 2) {
holder.res_name.setText("Shop");
holder.item_image.setBackgroundResource(R.drawable.shop_icon);
System.out.println("position == 2");
} else if (position == 3) {
holder.res_name.setText("Groupon");
holder.item_image.setBackgroundResource(R.drawable.groupon_icon);
System.out.println("position == 3");
}
myView.setTag(holder);
return myView;
}
我已经搜索并尝试了将近一天的解决方案,但没有任何效果,所以我决定 post 我的代码在这里,希望有人能给我一些帮助,谢谢!
我有一个扩展 ListFragment 的片段。
列表有四项;下面三个,我只是在我的私有ListAdapter class
中的getView()
方法中设置了他们的图片和文字。对于第一个,我想不断地改变它的画面。我有一个位图数组 promotion_image_array
,其中包含三个位图,我将用作第一项的源。以下是我的getView()
的代码和我现在得到的截图:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
View myView = convertView;
System.out.println("in getView");
if (myView == null) {
myView = inflater.inflate(R.layout.home_category_item, null);
holder = new ViewHolder();
holder.item_image= (ImageView)myView.findViewById(R.id.item_image);
holder.res_name = (TextView)myView.findViewById(R.id.res_name);
if(position == 0){
holder.res_name.setVisibility(View.GONE);
promotion_image_view = holder.item_image;
System.out.println("position == 0");
}
else if(position == 1) {
holder.res_name.setText("Food");
holder.item_image.setBackgroundResource(R.drawable.restaurant_icon);
System.out.println("position == 1");
}
else if(position == 2) {
holder.res_name.setText("Shop");
holder.item_image.setBackgroundResource(R.drawable.shop_icon);
System.out.println("position == 2");
}
else if(position == 3) {
holder.res_name.setText("Groupon");
holder.item_image.setBackgroundResource(R.drawable.groupon_icon);
System.out.println("position == 3");
}
myView.setTag(holder);
}
else {
// View recycled, no need to inflate
holder = (ViewHolder) myView.getTag();
}
return myView;
}
}
promotion_image_view = holder.item_image;
然后我尝试在我的运行nable的运行()方法中设置promotion_image_view的背景,下面是我的运行nable的代码和onCreate() 中的处理程序:
counter = 0;
mHandler = new MyHandler(this);
runnable = new Runnable() {
@Override
public void run() {
mHandler.postDelayed(runnable,3000);
// Repeatedly display three promotion images
Bitmap[] promotion_image_array = my_global_variables.city_config_object.config_promotion_image_array;
BitmapDrawable ob = new BitmapDrawable(my_resources, promotion_image_array[counter]);
if(promotion_image_view != null) {
promotion_image_view.setBackground(ob);
System.out.println("promotion_image_view != null");
}
System.out.format("in run: counter = %d%n", counter);
counter++;
if(counter == 3) counter = 0;
}
};
runnable.run();
promotion_image_view != null
和
in run: counter = %d%n
,计数器
正确打印(以恒定速率连续打印)并且计数器的值也正确。(0,1,2,0,1,2,0 .....)。但是画面一点变化都没有
非常感谢任何帮助,谢谢!!
********************************* 阅读一些答案后 --- 第一次编辑 ***** ***************************
感谢回答的人,我尝试了notifyDataSetChanged()方法,还是不行;图像未更改,但打印输出看起来正确。
修改后的代码如下:
getView() 方法:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
View myView = convertView;
if (myView == null) {
myView = inflater.inflate(R.layout.home_category_item, null);
holder = new ViewHolder();
holder.item_image= (ImageView)myView.findViewById(R.id.item_image);
holder.res_name = (TextView)myView.findViewById(R.id.res_name);
if(position == 0){
holder.res_name.setVisibility(View.GONE);
Bitmap[] promotion_image_array = my_global_variables.city_config_object.config_promotion_image_array;
BitmapDrawable ob = new BitmapDrawable(my_resources, promotion_image_array[counter]);
holder.item_image.setBackground(ob);
System.out.format("in run: counter = %d%n", counter);
counter++;
if(counter == 3) counter = 0;
System.out.println("in getView: position == 0");
}
else if(position == 1) {
holder.res_name.setText("Food");
holder.item_image.setBackgroundResource(R.drawable.restaurant_icon);
System.out.println("position == 1");
}
else if(position == 2) {
holder.res_name.setText("Shop");
holder.item_image.setBackgroundResource(R.drawable.shop_icon);
System.out.println("position == 2");
}
else if(position == 3) {
holder.res_name.setText("Groupon");
holder.item_image.setBackgroundResource(R.drawable.groupon_icon);
System.out.println("position == 3");
}
myView.setTag(holder);
}
else {
// View recycled, no need to inflate
holder = (ViewHolder) myView.getTag();
}
return myView;
}
}
handler 和 运行nable:
counter = 0;
mHandler = new MyHandler(this);
runnable = new Runnable() {
@Override
public void run() {
mHandler.postDelayed(runnable, 3000);
adapter.notifyDataSetChanged();
}
};
runnable.run();
下面是我认为正确的打印输出:
I/System.out﹕ in 运行: counter = 0
I/System.out﹕ in getView: position == 0
I/System.out﹕位置== 1
I/System.out﹕位置==2
I/System.out:位置== 3
I/System.out﹕ in 运行: counter = 1
I/System.out﹕ in getView: position == 0
I/System.out﹕ in 运行: counter = 2
I/System.out﹕ in getView: position == 0
I/System.out﹕ in 运行: counter = 0
I/System.out﹕ in getView: position == 0
I/System.out﹕ in 运行: counter = 1
I/System.out﹕ in getView: position == 0
I/System.out﹕ in 运行: counter = 2
I/System.out﹕ in getView: position == 0
I/System.out﹕ in 运行: counter = 0
I/System.out﹕ in getView: position == 0
使用静态变量 "promotion_image_view " 不是一个好主意。
因为,android 列表视图回收它自己的列表。见下文:
相反,使用图像幻灯片库怎么样?
https://github.com/daimajia/AndroidImageSlider
或,你可以更改你的真实数据(不是getView中生成的数据)然后像这样调用notifyDataSetChanged()方法.
runOnUiThread(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
});
编辑1:
重点是:if (myView == null)
您正在更新您的 imageView,仅当它 为 null 时。
那么,将该代码移到空检查代码之外怎么样?
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
View myView = convertView;
if (myView == null) {
myView = inflater.inflate(R.layout.home_category_item, null);
holder = new ViewHolder();
holder.item_image = (ImageView) myView.findViewById(R.id.item_image);
holder.res_name = (TextView) myView.findViewById(R.id.res_name);
} else {
// View recycled, no need to inflate
holder = (ViewHolder) myView.getTag();
}
if (position == 0) {
holder.res_name.setVisibility(View.GONE);
Bitmap[] promotion_image_array = my_global_variables.city_config_object.config_promotion_image_array;
BitmapDrawable ob = new BitmapDrawable(my_resources, promotion_image_array[counter]);
holder.item_image.setBackground(ob);
System.out.format("in run: counter = %d%n", counter);
System.out.println("in getView: position == 0");
counter = counter++ % 3;
} else if (position == 1) {
holder.res_name.setText("Food");
holder.item_image.setBackgroundResource(R.drawable.restaurant_icon);
System.out.println("position == 1");
} else if (position == 2) {
holder.res_name.setText("Shop");
holder.item_image.setBackgroundResource(R.drawable.shop_icon);
System.out.println("position == 2");
} else if (position == 3) {
holder.res_name.setText("Groupon");
holder.item_image.setBackgroundResource(R.drawable.groupon_icon);
System.out.println("position == 3");
}
myView.setTag(holder);
return myView;
}