奇妙な問題があります。ViewSwitcher でアクティビティを使用しています。この ViewSwitcher には、同じ を使用するListView
と があります。GridView
ArrayAdapter{SomeContent}
アダプターを作成して、アダプターが膨張に使用するものを渡すことができるようにしましたR.layout.value
。これは、これら2つのフォームで多少異なるビューが必要なため、ListView / GridView全体で一貫性を管理する方法です。
そして、これらすべてがある程度完全に機能しますが、これは初めてではありません.
いいえ、アプリケーションを GRID 表示モードで実行するのは初めてで、グリッドビューは間違った XML を使用しようとし、最終的には ListView の XML を使用 (リサイクル?) しようとします。GridView の XML にはチェックボックスの参照がなく、常に表示されるためです。
しかし、この画面を離れて (「アクティビティ」とは言いません)、戻ってくると、すべてが完全に膨らんでいます。リストは常にすぐに機能しますが、GridViews ~80% は初回のみ機能しません。
何か案は?
開始するためのコードを次に示します。アダプタ:
public class AudioAdapter extends ArrayAdapter<MusicContent>
{
private Context context;
private ImageView albumArt;
private TextView songName;
private TextView artistName;
private TextView albumName;
private TextView genre;
private TextView duration;
private int viewToUse;
private CheckBox checkbox;
private OnItemClickListener clickListener;
private OnItemSelectedListener focusListener;
private List<MusicContent> content = new ArrayList<MusicContent>();
public AudioAdapter(Context context, int textViewResourceId, List<MusicContent> objects,
OnItemClickListener clickListener, OnItemSelectedListener focusListener)
{
super(context, textViewResourceId, objects);
this.context = context;
this.content = objects;
this.clickListener = clickListener;
this.focusListener = focusListener;
this.viewToUse = textViewResourceId;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
/**
* Removed following optimization on purpose due to dynamically using
* different layouts which may result in wrong view being recycled for
* use
*/
//removing it fixed nothing really
if (row == null)
{
// ROW INFLATION
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(viewToUse, parent, false);
}
// initiate helpers for onClick hack
final AdapterView fParent = (AdapterView) parent;
final View fView = row;
final int fInt = position;
final long fLong = row.getId();
// Get item
MusicContent item = getItem(position);
if (item == null)
return row;
RelativeLayout root = (RelativeLayout) row.findViewById(R.id.list_cell_layout);
// perform a series of checks to maintain customizability
albumArt = (ImageView) row.findViewById(R.id.list_cell_image);
if (albumArt != null)
{
if (item.hasAlbumArt()) {
albumArt.setImageBitmap(item.getAlbumBitmap(context));
}
else
albumArt.setImageDrawable(context.getResources().getDrawable(
R.drawable.ic_music_album));
}
LinearLayout checkLL = (LinearLayout) row.findViewById(R.id.list_cell_music_info);
if (checkLL != null)
{
// display some song info
songName = (TextView) checkLL.findViewById(R.id.list_cell_title);
if (songName != null)
{
songName.setText(item.getDisplayName());
songName.setVisibility(View.VISIBLE);
}
// attach artificial OnItemClick and OnItemSelected listeners
if (clickListener != null)
{
OnClickListener cross = new OnClickListener() {
@Override
public void onClick(View v) {
Log.d("SHARK", "internal onClick from adapter!!" + fView);
clickListener.onItemClick(fParent, fView, fInt, fLong);
}
};
checkLL.setOnClickListener(cross);
}
if (focusListener != null)
{
OnFocusChangeListener cross = new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus)
focusListener.onItemSelected(fParent, fView, fInt, fLong);
}
};
checkLL.setOnFocusChangeListener(cross);
}
checkLL = (LinearLayout) row.findViewById(R.id.list_cell_artist_info);
if (checkLL != null)
{
// display artist info too
artistName = (TextView) checkLL.findViewById(R.id.list_cell_artist_name);
if (artistName != null)
artistName.setText(item.getArtist());
albumName = (TextView) checkLL.findViewById(R.id.list_cell_album);
if (albumName != null)
albumName.setText(item.getAlbum());
duration = (TextView) checkLL.findViewById(R.id.list_cell_duration);
if (duration != null)
duration.setText(item.getDurationString());
genre = (TextView) checkLL.findViewById(R.id.list_cell_genre);
if (genre != null)
genre.setText(item.getGenre());
// block focus on descendants
checkLL.setDescendantFocusability(RelativeLayout.FOCUS_BLOCK_DESCENDANTS);
// attach artificial listeners
if (clickListener != null)
{
OnClickListener cross = new OnClickListener() {
@Override
public void onClick(View v) {
Log.d("SHARK", "internal onClick from adapter!!" + fView);
clickListener.onItemClick(fParent, fView, fInt, fLong);
}
};
checkLL.setOnClickListener(cross);
}
if (focusListener != null)
{
OnFocusChangeListener cross = new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus)
focusListener.onItemSelected(fParent, fView, fInt, fLong);
}
};
checkLL.setOnFocusChangeListener(cross);
}
}
// FrameLayout checkFL = (FrameLayout)
// row.findViewById(R.id.endoflineinfo);
checkLL = (LinearLayout) row.findViewById(R.id.endoflineinfo);
if (checkLL != null)
{
checkbox = (CheckBox) checkLL.findViewById(R.id.in_playlist);
if (checkbox != null)
{
checkbox.setVisibility(View.VISIBLE);
if (item.getPlaylist() != null)
checkbox.setChecked(!item.getPlaylist().isEmpty());
}
checkLL.setDescendantFocusability(RelativeLayout.FOCUS_BLOCK_DESCENDANTS);
if (clickListener != null)
{
OnClickListener cross = new OnClickListener() {
@Override
public void onClick(View v) {
Log.d("SHARK", "internal onClick from adapter!!" + fView);
clickListener.onItemClick(fParent, fView, fInt, fLong);
}
};
checkLL.setOnClickListener(cross);
}
if (focusListener != null)
{
OnFocusChangeListener cross = new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus)
focusListener.onItemSelected(fParent, fView, fInt, fLong);
}
};
checkLL.setOnFocusChangeListener(cross);
}
}
}
// magic happens where we bind an OnItemClick call to OnClick
root.setDescendantFocusability(RelativeLayout.FOCUS_BLOCK_DESCENDANTS);
if (clickListener != null)
{
OnClickListener cross = new OnClickListener() {
@Override
public void onClick(View v) {
Log.d("SHARK", "internal onClick from adapter!!");
clickListener.onItemClick(fParent, fView, fInt, fLong);
}
};
// assign this listener
root.setOnClickListener(cross);
}
if (focusListener != null)
{
OnFocusChangeListener cross = new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus)
focusListener.onItemSelected(fParent, fView, fInt, fLong);
}
};
root.setOnFocusChangeListener(cross);
}
return row;
}
なぜこれほど多くの if とチェックが行われるのかについては、要素が欠落しているさまざまな基礎となる XML (カスタマイズ可能性) に耐えられる必要があり、onClick / onFocus ハックについてあまり心配する必要はありません。