2016-08-25 87 views
1

我有一個包含文本和圖像的gridview。當用戶觸摸網格中的一個單元格時,它將更改顏色以顯示它已被選中,並且當再次選中時,它會返回到默認顏色以顯示它不再被選中。任何數量的細胞都可以選擇。問題是,當用戶必須滾動瀏覽網格才能看到所選圖標有時變爲未選中並選擇「隨機」的其他單元。 我懷疑這與gridview被回收有關,但我不確定如何解決這個問題。更改點擊gridview單元格的顏色

public class Onboarding extends Activity { 
GridView grid; 
ArrayList selectedCategories = new ArrayList<>(); 
CustomGrid adapter; 
String[] dummyString = { 
     "item 1", 
     "item 2", 
     "item 3", 
     "item 4", 
     "item 5", 
     "item 6", 
     "item 7", 
     "item 8", 
     "item 9", 
     "item 10", 
     "item 11", 
     "item 12", 
     "item 13", 
     "item 14", 
     "item 15", 
     "item 16", 
     "item 17", 
     "item 18", 
     "item 19" 
}; 
int[] imageId = { 
     R.drawable.1, 
     R.drawable.2, 
     R.drawable.3, 
     R.drawable.4, 
     R.drawable.5, 
     R.drawable.6, 
     R.drawable.7, 
     R.drawable.8, 
     R.drawable.9, 
     R.drawable.10, 
     R.drawable.11, 
     R.drawable.12, 
     R.drawable.13, 
     R.drawable.14, 
     R.drawable.15, 
     R.drawable.16, 
     R.drawable.17, 
     R.drawable.18, 
     R.drawable.19 
}; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_onboarding); 
    getWindow().setSoftInputMode(
      WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN 
    ); //makes sure keyboard is hidden on this view as it is not needed 
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT); 

    grid = (GridView) findViewById(R.id.grid); 

    //deals with settings the number of Columns 
    DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics(); 
    double dpWidth = displayMetrics.widthPixels/displayMetrics.density; 
    if (dpWidth <= 400) { 
     grid.setNumColumns(2); 
    } else if (dpWidth > 400 && dpWidth < 500) { 
     grid.setNumColumns(3); 
    } else if (dpWidth >= 500 && dpWidth < 550) { 
     grid.setNumColumns(4); 
    } else { 
     grid.setNumColumns(5); 
    } 

    adapter = new CustomGrid(Onboarding.this, dummyString, imageId); 
    grid.setAdapter(adapter); 
    grid.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, 
           int position, long id) { 
      //the position is the actual position that is pressed. but the getChildAt returns gets the relative position, ie what's being drawn 
      //on the grid. 
      //to fix this, the first visible position is obtained and the difference is subtracted 
      int firstPos = grid.getFirstVisiblePosition(); 
      View tv = grid.getChildAt(position - firstPos); 
      Toast.makeText(Onboarding.this, "You Clicked at position" + position + " " + dummyString[+position] + "firstPos " + firstPos, Toast.LENGTH_SHORT).show(); //debug 

      if (tv == null) { //this shouldn't/doesn't happen 
       Log.e("OnBoarding.java", "Issue with null view at line " + Thread.currentThread().getStackTrace()[2].getLineNumber() + 
         "grid is having a problem"); 
       return; 
      } 

      if (selectedCategories.contains(dummyString[+position]) == false) {//add the item if it doesn't exist 
       selectedCategories.add(dummyString[+position]); 
       tv.setBackgroundColor(Color.parseColor("#FFE5CD")); 
      } else { //remove the item if it already exists, as the user is removing it by touching it again 
       selectedCategories.remove(dummyString[+position]); 
       tv.setBackgroundColor(Color.parseColor("#EEEEEE")); 
      } 
     } 
    }); 

} 

}

public class CustomGrid extends BaseAdapter { 
private Context mContext; 
private final String[] genreString; 
private final int[] Imageid; 

public CustomGrid(Context c, String[] genreString, int[] Imageid) { 
    mContext = c; 
    this.Imageid = Imageid; 
    this.genreString = genreString; 
} 

@Override 
public int getCount() { 
    return genreString.length; 
} 

@Override 
public Object getItem(int position) { 
    return null; 
} 

@Override 
public long getItemId(int position) { 
    return 0; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View grid; 
    LayoutInflater inflater = (LayoutInflater) mContext 
      .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    TextView textView; 
    ImageView imageView; 
    if (convertView == null) { 
     grid = inflater.inflate(R.layout.grid_single, null); 
    } else { 
     grid = convertView; 
    } 
    textView = (TextView) grid.findViewById(R.id.grid_text); 
    imageView = (ImageView) grid.findViewById(R.id.grid_image); 
    textView.setText(genreString[position]); 
    imageView.setImageResource(Imageid[position]); 

    return grid; 
} 

}

回答

1

我最終做了什麼來解決這個問題,是在gridview上使用滾動監聽器。

 grid.setOnScrollListener(new AbsListView.OnScrollListener() { 
     @Override 
     public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
      //Log.d("Onboarding 7331", "onScroll: onScroll " + firstVisibleItem + " " + selectedPositions.toString()); 
      for (int i = 0; i < totalItemCount; i++) { 
       View tv = grid.getChildAt(i - firstVisibleItem); 
       if (tv == null) { 
        continue; 
       } 
       if (selectedPositions.contains(Integer.toString(i))) { 
        tv.setBackgroundColor(Color.parseColor("#FFE5CD")); 
       } else { 
        tv.setBackgroundColor(Color.parseColor("#EEEEEE")); 
       } 
      } 
     } 

     @Override 
     public void onScrollStateChanged(AbsListView view, int scrollState) { 
      //  Log.d("Onboarding 7331", "onScroll: state changed "+selectedPositions.toString()); 
     } 
    }); 
1

步驟變更點擊gridview的項目

1)創建像

在側繪製選擇一個顏色
<item android:drawable="@color/blue" android:state_pressed="true" /> 
<item android:drawable="@color/blue" android:state_selected="true" /> 
<item android:drawable="@color/white" /> 

2)設置背景網格視圖項目佈局像

android:background="@drawable/grid_color_selector" 

希望它會爲你工作。