Android ListView 错误的 Item 更新
Android ListView wrong Item Update
首先,我将解释我想要做什么,我将 post 下面的代码。
我有一个蓝牙服务,一个带有自定义适配器的 ListView 和一个蓝牙服务的处理程序,如果 phone 已连接,它将通知 ||连接 ||与 BT 设备断开连接。
我的 ListView 包含附近的蓝牙设备,例如,单击项目标签时会更新,phone 将连接到该设备。
假设我有 2 个 BT 设备。如果我 select 第一个,第一个的标签将被更新(这是正确的), 但是如果我 select 项目编号。 2,出于某种原因,它也更新了第一个标签 <- 这就是问题所在
我在我的应用程序中使用片段,ListViewAdapter 的代码和要更新的方法如下:
列表视图适配器代码:
public class BluetoothListViewAdapter extends ArrayAdapter<HashMap<String, String>>{
Context ctx;
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private LayoutInflater inflater = null;
CircularProgressButton Device = null;
public BluetoothListViewAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
super(a,R.layout.template_bluetooth_listview_element,d);
ctx = a.getBaseContext();
activity = a;
data = d;
inflater = (LayoutInflater) a.getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return data.size();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
String TAG;
String MAC;
View vi = convertView;
if (vi == null)
vi = inflater.inflate(R.layout.template_bluetooth_listview_element, null);
Device = null;
Device = (CircularProgressButton) vi.findViewById(R.id.CircularProgressButton_BluetoothListElement);
HashMap<String, String> category = new HashMap<String, String>();
category = data.get(position);
TAG = (category.get("TAG"));
MAC = (category.get("MAC"));
Device.setText(TAG + "\n" + MAC);
Device.setIdleText(TAG + "\n" + MAC);
if(GlobalActivity.CurrentDeviceTAG.equals(TAG) && GlobalActivity.CurrentDeviceMAC.equals(MAC) && position == GlobalActivity.CurrentDevicePosition) { // if the selected device is the one i am connected
if (GlobalActivity.BluetoothConnectionStatus == GlobalActivity.STATE_CONNECTED) {
Device.setIndeterminateProgressMode(false);
Device.setProgress(100); // -- update GUI Element
}
if (GlobalActivity.BluetoothConnectionStatus == GlobalActivity.STATE_NONE) {
Device.setIndeterminateProgressMode(false);
Device.setProgress(0); // -- update GUI Element
}
}
return vi;
}
}
蓝牙片段代码(位置保存在 public static int 中的连接尝试):
public void BluetoothStateChanged(int position){
Adapter.getView(position, null, null);
Adapter.notifyDataSetChanged();
BluetoothDeviceListView.setAdapter(Adapter);
}
上述方法由蓝牙服务处理程序在状态更改时调用 - 此更新是 GUI 元素。
抱歉我的英语和解释不好。我有27小时没有睡觉。
我真的需要解决这个问题。
谢谢你的时间
根据要求更新 - 列表视图项目布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#424242">
<com.dd.CircularProgressButton
android:id="@+id/CircularProgressButton_BluetoothListElement"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginTop="16dp"
android:textColor="#FFFFFF"
android:textSize="18sp"
app:cpb_cornerRadius="48dp"
app:cpb_iconComplete="@drawable/ic_action_accept"
app:cpb_iconError="@drawable/ic_action_cancel"
android:focusable="false"
android:clickable="false" />
</LinearLayout>
您需要创建一个带有进度条的 class,并且每当您在 getView() 中创建一个视图时,将此容器 class 设置为标签。
见以下代码:
public class BluetoothListViewAdapter extends ArrayAdapter<HashMap<String, String>>{
Context ctx;
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private LayoutInflater inflater = null;
public BluetoothListViewAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
super(a,R.layout.template_bluetooth_listview_element,d);
ctx = a.getBaseContext();
activity = a;
data = d;
inflater = (LayoutInflater) a.getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return data.size();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
String TAG;
String MAC;
View vi = convertView;
Holder holder;
if (vi == null)
{
vi = inflater.inflate(R.layout.template_bluetooth_listview_element, null);
holder.Device = (CircularProgressButton) vi.findViewById(R.id.CircularProgressButton_BluetoothListElement);
vi.setTag(holder);
}
else
holder = (Holder) vi.getTag();
HashMap<String, String> category = new HashMap<String, String>();
category = data.get(position);
TAG = (category.get("TAG"));
MAC = (category.get("MAC"));
holder.Device.setText(TAG + "\n" + MAC);
holder.Device.setIdleText(TAG + "\n" + MAC);
if(GlobalActivity.CurrentDeviceTAG.equals(TAG) && GlobalActivity.CurrentDeviceMAC.equals(MAC) && position == GlobalActivity.CurrentDevicePosition) { // if the selected device is the one i am connected
if (GlobalActivity.BluetoothConnectionStatus == GlobalActivity.STATE_CONNECTED) {
holder.Device.setIndeterminateProgressMode(false);
holder.Device.setProgress(100); // -- update GUI Element
}
if (GlobalActivity.BluetoothConnectionStatus == GlobalActivity.STATE_NONE) {
holder.Device.setIndeterminateProgressMode(false);
holder.Device.setProgress(0); // -- update GUI Element
}
}
return vi;
}
class Holder{
CircularProgressButton Device;
}
}
public void BluetoothStateChanged(){
int start = BluetoothDeviceListView.getFirstVisiblePosition();
for(int i = start, j = BluetoothDeviceListView.getLastVisiblePosition(); i<=j; i++) {
View view = BluetoothDeviceListView.getChildAt(i - start);
if ((BluetoothDeviceListView.getItemAtPosition(i)) != null) {
BluetoothDeviceListView.getAdapter().getView(i, view, BluetoothDeviceListView); // Tell the adapter to update this view
}
}
}
首先,我将解释我想要做什么,我将 post 下面的代码。 我有一个蓝牙服务,一个带有自定义适配器的 ListView 和一个蓝牙服务的处理程序,如果 phone 已连接,它将通知 ||连接 ||与 BT 设备断开连接。
我的 ListView 包含附近的蓝牙设备,例如,单击项目标签时会更新,phone 将连接到该设备。
假设我有 2 个 BT 设备。如果我 select 第一个,第一个的标签将被更新(这是正确的), 但是如果我 select 项目编号。 2,出于某种原因,它也更新了第一个标签 <- 这就是问题所在
我在我的应用程序中使用片段,ListViewAdapter 的代码和要更新的方法如下:
列表视图适配器代码:
public class BluetoothListViewAdapter extends ArrayAdapter<HashMap<String, String>>{
Context ctx;
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private LayoutInflater inflater = null;
CircularProgressButton Device = null;
public BluetoothListViewAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
super(a,R.layout.template_bluetooth_listview_element,d);
ctx = a.getBaseContext();
activity = a;
data = d;
inflater = (LayoutInflater) a.getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return data.size();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
String TAG;
String MAC;
View vi = convertView;
if (vi == null)
vi = inflater.inflate(R.layout.template_bluetooth_listview_element, null);
Device = null;
Device = (CircularProgressButton) vi.findViewById(R.id.CircularProgressButton_BluetoothListElement);
HashMap<String, String> category = new HashMap<String, String>();
category = data.get(position);
TAG = (category.get("TAG"));
MAC = (category.get("MAC"));
Device.setText(TAG + "\n" + MAC);
Device.setIdleText(TAG + "\n" + MAC);
if(GlobalActivity.CurrentDeviceTAG.equals(TAG) && GlobalActivity.CurrentDeviceMAC.equals(MAC) && position == GlobalActivity.CurrentDevicePosition) { // if the selected device is the one i am connected
if (GlobalActivity.BluetoothConnectionStatus == GlobalActivity.STATE_CONNECTED) {
Device.setIndeterminateProgressMode(false);
Device.setProgress(100); // -- update GUI Element
}
if (GlobalActivity.BluetoothConnectionStatus == GlobalActivity.STATE_NONE) {
Device.setIndeterminateProgressMode(false);
Device.setProgress(0); // -- update GUI Element
}
}
return vi;
}
}
蓝牙片段代码(位置保存在 public static int 中的连接尝试):
public void BluetoothStateChanged(int position){
Adapter.getView(position, null, null);
Adapter.notifyDataSetChanged();
BluetoothDeviceListView.setAdapter(Adapter);
}
上述方法由蓝牙服务处理程序在状态更改时调用 - 此更新是 GUI 元素。
抱歉我的英语和解释不好。我有27小时没有睡觉。
我真的需要解决这个问题。
谢谢你的时间
根据要求更新 - 列表视图项目布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#424242">
<com.dd.CircularProgressButton
android:id="@+id/CircularProgressButton_BluetoothListElement"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginTop="16dp"
android:textColor="#FFFFFF"
android:textSize="18sp"
app:cpb_cornerRadius="48dp"
app:cpb_iconComplete="@drawable/ic_action_accept"
app:cpb_iconError="@drawable/ic_action_cancel"
android:focusable="false"
android:clickable="false" />
</LinearLayout>
您需要创建一个带有进度条的 class,并且每当您在 getView() 中创建一个视图时,将此容器 class 设置为标签。
见以下代码:
public class BluetoothListViewAdapter extends ArrayAdapter<HashMap<String, String>>{
Context ctx;
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private LayoutInflater inflater = null;
public BluetoothListViewAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
super(a,R.layout.template_bluetooth_listview_element,d);
ctx = a.getBaseContext();
activity = a;
data = d;
inflater = (LayoutInflater) a.getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return data.size();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
String TAG;
String MAC;
View vi = convertView;
Holder holder;
if (vi == null)
{
vi = inflater.inflate(R.layout.template_bluetooth_listview_element, null);
holder.Device = (CircularProgressButton) vi.findViewById(R.id.CircularProgressButton_BluetoothListElement);
vi.setTag(holder);
}
else
holder = (Holder) vi.getTag();
HashMap<String, String> category = new HashMap<String, String>();
category = data.get(position);
TAG = (category.get("TAG"));
MAC = (category.get("MAC"));
holder.Device.setText(TAG + "\n" + MAC);
holder.Device.setIdleText(TAG + "\n" + MAC);
if(GlobalActivity.CurrentDeviceTAG.equals(TAG) && GlobalActivity.CurrentDeviceMAC.equals(MAC) && position == GlobalActivity.CurrentDevicePosition) { // if the selected device is the one i am connected
if (GlobalActivity.BluetoothConnectionStatus == GlobalActivity.STATE_CONNECTED) {
holder.Device.setIndeterminateProgressMode(false);
holder.Device.setProgress(100); // -- update GUI Element
}
if (GlobalActivity.BluetoothConnectionStatus == GlobalActivity.STATE_NONE) {
holder.Device.setIndeterminateProgressMode(false);
holder.Device.setProgress(0); // -- update GUI Element
}
}
return vi;
}
class Holder{
CircularProgressButton Device;
}
}
public void BluetoothStateChanged(){
int start = BluetoothDeviceListView.getFirstVisiblePosition();
for(int i = start, j = BluetoothDeviceListView.getLastVisiblePosition(); i<=j; i++) {
View view = BluetoothDeviceListView.getChildAt(i - start);
if ((BluetoothDeviceListView.getItemAtPosition(i)) != null) {
BluetoothDeviceListView.getAdapter().getView(i, view, BluetoothDeviceListView); // Tell the adapter to update this view
}
}
}