我有列表,其中包含两个textview和一个imageview。我使用ArrayAdapter给列表充气。除了在点击时更改列表项颜色外,一切正常。我的列表视图中有22个项目。主要是listview在屏幕上显示10个项目,并在滚动时获取其他项目。现在我的问题是当我点击0-9(最初的10个项目)之间的单项时,项目在点击时正确地改变了颜色,但是当我滚动并点击时对于位置大于9的项目(在最初的10个项目之后),我的活动崩溃了。我在http://www.mail-archive.com/android-developers@googlegroups.com/msg09740.html链接中编写for loop
中的代码。帮助我摆脱这个问题。任何建议或者解决方案将受到高度赞赏。提前提交。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); // to hide the virtual keyboard
setContentView(R.layout.defect_pic_listview);
try{
adapter = new MyArrayAdapter(this,makeList());
setListAdapter(adapter);
adapter.notifyDataSetChanged();
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
getListView().setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// Toast.makeText(getApplicationContext(), "Item "+position+" is clicked",
// Toast.LENGTH_SHORT).show();
System.out.println("position"+position);
int first = getListView().getFirstVisiblePosition();
System.out.println("first="+first);
int last = getListView().getLastVisiblePosition();
System.out.println("last="+last);
int total = last - first;
System.out.println("total="+total);
if(getListView().isItemChecked(position)){
for(int i = 0 ; i <= last ; i++){
System.out.println("i="+i);
if(first+i == position){
getListView().getChildAt(i).setBackgroundColor(Color.GREEN);
System.out.println("l1="+getListView());
// l.getItemAtPosition(i);
// System.out.println("l position"+l);
}
else{
getListView().getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
System.out.println("l2="+getListView());
}
}
}
else{
getListView().getChildAt(position - first).setBackgroundColor(Color.TRANSPARENT);
}
}
});
}
catch(Exception e){
Log.d("error",e.getMessage());
}
}
答案 0 :(得分:0)
将此代码用于for循环。
if(getListView().isItemChecked(position))
{
for(int i = 0 ; i < total ; i++)
{
System.out.println("i="+i);
if(first+i == position)
{
getListView().getChildAt(i).setBackgroundColor(Color.GREEN);
System.out.println("l1="+getListView());
// l.getItemAtPosition(i);
// System.out.println("l position"+l);
}
else
{
getListView().getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
System.out.println("l2="+getListView
());
}
}
我认为您打算只更改点击项目的bacground颜色。为此,您不需要添加for循环。如果您的意图与我所说的相同,那么只在for循环的地方使用此代码。
getListView().getChildAt(position).setBackgroundColor(Color.GREEN);
答案 1 :(得分:0)
还有其他办法。
首先你需要添加一个选择器xml,例如listviewitem_bg.xml
<item android:drawable="@drawable/listview_normal" android:state_enabled="true" android:state_pressed="false"/> <item android:drawable="@drawable/listview_press" android:state_enabled="true" android:state_pressed="true"/>
然后将其设置为列表视图单元格的背景。
答案 2 :(得分:0)
您可以尝试这样:
public class CustomAdapter extends ArrayAdapter<String> {
String[] array;
Context mContext;
LayoutInflater mInflater;
int[] itemStates;
public CustomAdapter(Context context, int textViewResourceId,
String[] objects)
{
super(context, textViewResourceId, objects);
array=objects;
mContext=context;
mInflater = LayoutInflater.from(context);
//save all buttons state as 0(not clicked) initially
itemStates=new int[objects.length];
for(int i=0;i<objects.length;i++)
{
itemStates[i]=0;
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
final ViewHolder holder;
if(convertView==null)
{
convertView = mInflater.inflate(R.layout.custom_listitem, null);
holder = new ViewHolder();
holder.text=(TextView)convertView.findViewById(R.id.text);
holder.layout=(LinearLayout)convertView.findViewById(R.id.linear_layout); // outer most linear layout iin custom_listitem xml
convertView.setTag(holder);
}
else
holder=(ViewHolder)convertView.getTag();
holder.text.setText(array[position]);
if(itemStates[position]==0)
{
holder.layout.setBackgroundResource(R.drawable.red_gradient); // item is not clicked/selected yet
}
else
{
holder.button.setBackgroundResource(R.drawable.green_gradient); // item is clicked/selected so change its color
}
final int pos=position;
holder.layout.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
itemStates[pos]=1;
holder.button.setBackgroundResource(R.drawable.green_gradient);
}
});
return convertView;
}
static class ViewHolder
{
TextView text;
LinearLayout layout;
}
}
这会给你以下行为:
答案 3 :(得分:0)
你可以做这样的事情
@在创建之外
View prevView;
然后在oncreate
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View view, int arg2,
long arg3) {
if (prevView != null) {
prevView.setBackgroundColor(Color.TRANSPARENT);
}
view.setBackgroundColor(Color.RED);
prevView = view;
}
});
答案 4 :(得分:0)
我正在回答我自己的问题。
这是完美的运行代码: -
getListView().setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// Toast.makeText(getApplicationContext(), "Item "+position+" is clicked",
// Toast.LENGTH_SHORT).show();
System.out.println("position="+position);
int first = getListView().getFirstVisiblePosition();
System.out.println("first="+first);
int last = getListView().getLastVisiblePosition();
System.out.println("last="+last);
int total = last - first;
System.out.println("total="+total);
if(getListView().isItemChecked(position)){
for(int i = first ; i <= last ; i++){
System.out.println("i="+i);
if(i == position){
Log.w("TAG", "I am in If block");
getListView().getChildAt(i-first).setBackgroundColor(Color.GREEN);
System.out.println("l1="+getListView());
// l.getItemAtPosition(i);
// System.out.println("l position"+l);
}
else{
getListView().getChildAt(i-first).setBackgroundColor(Color.TRANSPARENT);
System.out.println("l2="+getListView());
}
}
}
else{
getListView().getChildAt(position).setBackgroundColor(Color.TRANSPARENT);
}
}
});
答案 5 :(得分:0)
我成功使用的一个清洁(?)解决方案是创建一个LinearLayout扩展小部件(或用于listitem布局的任何根视图类型),它实现Checkable。
public class CheckableLinearLayout extends LinearLayout implements Checkable {
boolean checked = false;
public CheckableLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CheckableLinearLayout(Context context) {
super(context);
}
@Override
public void setChecked(boolean checked) {
this.checked = checked;
updateView();
}
/* (non-Javadoc)
* @see android.widget.Checkable#isChecked()
*/
@Override
public boolean isChecked() {
return this.checked;
}
/* (non-Javadoc)
* @see android.widget.Checkable#toggle()
*/
@Override
public void toggle() {
this.checked=!this.checked;
updateView();
}
private void updateView() {
if (this.checked) {
//Change to Whatever your checked color should be, maybe expose this as attribute so i't can be changed from xml attribute
setBackgroundResource(R.color.default_background_color);
} else {
setBackgroundDrawable(null);
}
invalidate();
}
}
然后在你的项目布局xml:
<my.app.widgets.CheckableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
..any views for your listitem
<my.app.widgets.CheckableLinearLayout/>