问题
I have created a custom list view adapter, which is like a table with rows and columns.
I have not fully understand yet, how getView method works.
the last colum of each row, I have placed a reject button. When I press this button, it deletes the specific row.
The problem is that it does not delete the row when I press, instead it deletes another row.
I quote the code of the custom adapter
public class ListViewAdapter extends BaseAdapter
{
public final String TAG = getClass().getSimpleName();
public ArrayList<HashMap<String, String>> list;
Activity activity;
TextView txtFirst;
TextView txtSecond;
TextView txtThird;
TextView txtFourth;
ImageView imgView;
//Button btn_con;
ImageView btn_con,btn_rej;
Button btn_popup;
PopupWindow m_popupWindow;
private RelativeLayout m_relativeLayout;
public ListViewAdapter(Activity activity, ArrayList<HashMap<String, String>> list)
{
super();
this.activity = activity;
this.list = list;
}
@Override
public int getCount()
{
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int position)
{
// TODO Auto-generated method stub
return list.get(position);
}
@Override
public long getItemId(int position)
{
// TODO Auto-generated method stub
return 0;
}
public void updateItem(JSONObject p_jsonObject)
{
Log.d(TAG,"update custom list view");
String id_ka=null,sw_ka=null,hw_ka=null,battery_ka=null,sw_color=null;
try
{
id_ka = p_jsonObject.getString("id_ka");
sw_ka = p_jsonObject.getJSONObject("sw_ka").getString("version");
sw_color = p_jsonObject.getJSONObject("sw_ka").getString("color");
hw_ka = p_jsonObject.getJSONObject("hw_ka").getString("version");
battery_ka = p_jsonObject.getJSONObject("battery_ka").getString("level");
}
catch (JSONException p_e)
{
p_e.printStackTrace();
}
for(int i=0;i<list.size();i++)
{
if(list.get(i).get("id").equals(id_ka))
{
list.get(i).put(SWVERSION,sw_ka);
list.get(i).put(HWVERSION,hw_ka);
list.get(i).put(BATTERY_LEVEL,battery_ka);
list.get(i).put(SWVERSION_COLOR,sw_color);
}
}
}
public boolean checkIfIdExistsInList(JSONObject p_jsonObject)
{
if (list == null)
{
Log.d(TAG,"List has not created");
}
if(list.size()==0)
{
Log.d(TAG,"List has 0 elements");
return false;
}
String id_ka = null;
try
{
id_ka = p_jsonObject.getString("id_ka");
}
catch (JSONException p_e)
{
p_e.printStackTrace();
}
for(int i=0;i<list.size();i++)
{
if (list.get(i).get("id").equals(id_ka))
{
Log.d(TAG,"ka with id "+id_ka+" exists in the list");
return true;
}
}
Log.d(TAG,"ka with id " +id_ka+" does not exist in the list");
return false;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
final LayoutInflater inflater = activity.getLayoutInflater();
if (convertView == null)
{
convertView = inflater.inflate(R.layout.column_row, (ViewGroup)null);
m_relativeLayout = (RelativeLayout) convertView.findViewById(R.id.activity_main);
txtFirst = (TextView) convertView.findViewById(R.id.ka_id);
txtSecond = (TextView) convertView.findViewById(R.id.battery_volt);
txtThird = (TextView) convertView.findViewById(R.id.sw_version);
txtFourth = (TextView) convertView.findViewById(R.id.image);
imgView = (ImageView)convertView.findViewById(R.id.imgView);
btn_con = (ImageView)convertView.findViewById(R.id.btn_con);
btn_rej = (ImageView)convertView.findViewById(R.id.btn_rej);
}
final HashMap<String, String> map = list.get(position);
Log.d(TAG, map.get(KA_ID) + " updates UI in position " + String.valueOf(position));
txtFirst.setText(map.get(KA_ID));
txtSecond.setText(map.get(SWVERSION));
txtSecond.setBackgroundColor(Color.parseColor(map.get(SWVERSION_COLOR)));
txtThird.setText(map.get(HWVERSION));
txtFourth.setText(map.get(BATTERY_LEVEL));
btn_rej.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
list.remove(position);
notifyDataSetChanged();
}
});
return convertView;
}
}
my main activity
public class MainActivity extends AppCompatActivity
{
private final String TAG = getClass().getSimpleName();
private ArrayList<HashMap<String,String>> list;
private static int obj_id =0;
Button bn;
Handler resultHandler;
DoSomethingThread randomWork;
ListView lv,lv_header;
ListViewAdapter customAdapter;
LinearLayout ln;
private String file_name = null;
private String jsonobj = null;
Random rand;
Button btn_show,btn_update,btn_remove,btn_popup;
JSONObject jobjDemo;
PopupWindow m_popupWindow;
LayoutInflater m_layoutInflater;
RelativeLayout m_relativeLayout;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(R.layout.progressbar);
setContentView(R.layout.activity_main);
createButtons();
lv = (ListView)findViewById(R.id.mainLV);
list = new ArrayList<HashMap<String, String>>();
}
private void createButtons()
{
m_relativeLayout = (RelativeLayout) findViewById(R.id.activity_main);
btn_popup = (Button)findViewById(R.id.btn_popup);
btn_popup.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
m_layoutInflater = (LayoutInflater)getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE);
ViewGroup container = (ViewGroup) m_layoutInflater.inflate(R.layout.popup,null);
m_popupWindow = new PopupWindow(container,400,400,true);
m_popupWindow.showAtLocation(m_relativeLayout, Gravity.NO_GRAVITY,500,500);
container.setOnTouchListener((
new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
m_popupWindow.dismiss();
return true;
}
}));
}
});
btn_show = (Button) findViewById(R.id.btn_show);
btn_show.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
boolean id_exist = false;
if(customAdapter != null)
{
id_exist = customAdapter.checkIfIdExistsInList(jobjDemo);
}
if(id_exist)
{
Log.d(TAG,"id exists in list view, updating...");
updateListView(jobjDemo);
}
else
{
Log.d(TAG,"id does not exist in list view, add element...");
startGenerating(jobjDemo);
}
}
});
btn_update = (Button)findViewById(R.id.btn_update);
btn_update.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Log.d(TAG,"JSON file has been updated");
String json_path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath();
jobjDemo = getJSonFromFile(json_path+"/test.json");
}
});
btn_remove = (Button)findViewById(R.id.btn_remove);
btn_remove.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Log.d(TAG,"remove element from custom list view");
}
});
}
private void updateListView(JSONObject p_jsonObject)
{
if (lv.getAdapter()== null)
{
Log.d(TAG,"ListView has not created yet");
return;
}
if (lv.getAdapter().getCount() == 0)
{
Log.d(TAG, "ListView has 0 elements");
return;
}
customAdapter.updateItem(p_jsonObject);
customAdapter.notifyDataSetChanged();
lv.setAdapter(customAdapter);
}
private void startGenerating(JSONObject p_jsonObject)
{
String id_ka=null,sw_ka=null,hw_ka=null,battery_ka=null,sw_color=null;
getWindow().getDecorView().getRootView().findViewById(R.id.list_headers).setVisibility(LinearLayout.VISIBLE);
try
{
id_ka = p_jsonObject.getString("id_ka");
sw_ka = p_jsonObject.getJSONObject("sw_ka").getString("version");
sw_color = p_jsonObject.getJSONObject("sw_ka").getString("color");
hw_ka = p_jsonObject.getJSONObject("hw_ka").getString("version");
battery_ka = p_jsonObject.getJSONObject("battery_ka").getString("level");
}
catch (JSONException p_e)
{
p_e.printStackTrace();
}
HashMap<String,String> temp = new HashMap<String,String>();
temp.put(KA_ID,id_ka);
temp.put(SWVERSION,sw_ka);
temp.put(SWVERSION_COLOR,sw_color);
temp.put(HWVERSION,hw_ka);
temp.put(BATTERY_LEVEL,battery_ka);
list.add(temp);
customAdapter=new ListViewAdapter(this, list);
lv.setAdapter(customAdapter);
}
@Override
public void onResume()
{
super.onResume();
Log.d(TAG,"Data has changed");
}
}
What I have done so far and it is working but I am not sure that this is the right implementation is to make public and static the custom adapter and use the same object inside custom adapter.
Any suggestions, thanks for your help!
回答1:
try this one
Create new Interface name DeleteRow like this :
public interface DeleteRow {
void deleteRow(int position);
}
In your MainActivity add
implements DeleteRow
Like this
public class MainActivity extends AppCompatActivity implements DeleteRow{
// your class
@Override
public void deleteRow(int position) {
list.remove(position);
listView.removeViewAt(position);
listViewAdapter.notifyItemRemoved(position);
listViewAdapter.notifyItemRangeChanged(position, list.size());
}
}
add this parameter to your adapter
customAdapter = new ListViewAdapter(... , this);
In ListViewAdapter add
DeleteRow deleterow;
public ListViewAdapter(Activity activity, ArrayList<HashMap<String, String>> list, DeleteRow deleterow)
{
super();
this.activity = activity;
this.list = list;
this.deleterow = deleterow;
}
in the clickListener
btn_remove.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
deleteRow.deleteRow(position);
Log.d(TAG,"remove element from custom list view");
}
});
回答2:
try this
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
final LayoutInflater inflater = activity.getLayoutInflater();
if (convertView == null)
{
convertView = inflater.inflate(R.layout.column_row, (ViewGroup)null);
m_relativeLayout = (RelativeLayout) convertView.findViewById(R.id.activity_main);
txtFirst = (TextView) convertView.findViewById(R.id.ka_id);
txtSecond = (TextView) convertView.findViewById(R.id.battery_volt);
txtThird = (TextView) convertView.findViewById(R.id.sw_version);
txtFourth = (TextView) convertView.findViewById(R.id.image);
imgView = (ImageView)convertView.findViewById(R.id.imgView);
btn_con = (ImageView)convertView.findViewById(R.id.btn_con);
btn_rej = (ImageView)convertView.findViewById(R.id.btn_rej);
}
final HashMap<String, String> map = list.get(position);
Log.d(TAG, map.get(KA_ID) + " updates UI in position " + String.valueOf(position));
txtFirst.setText(map.get(KA_ID));
txtSecond.setText(map.get(SWVERSION));
txtSecond.setBackgroundColor(Color.parseColor(map.get(SWVERSION_COLOR)));
txtThird.setText(map.get(HWVERSION));
txtFourth.setText(map.get(BATTERY_LEVEL));
btn_rej.setTag(position);
btn_rej.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
int rposition=v.getTag();
list.remove(rposition);
notifyDataSetChanged();
}
});
return convertView;
}
回答3:
all the above solutions does not work. Instead if I will turn the customAdapter and lv to public and static in Mainactivity
public static ListView lv;
public static ListViewAdapter customAdapter;
and at the inside the ListViewAdapter
btn_rej.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
list.remove(position);
customAdapter.notifyDataSetChanged();
lv.setAdapter(customAdapter);
}
});
this will do the job. But as I told I do not know if it is the right approach.
回答4:
You can try the following code
list.remove(position + 1);
notifyDataSetChanged();
来源:https://stackoverflow.com/questions/40651697/when-i-press-a-button-which-exists-inside-the-custom-list-view-it-deletes-anothe