尝试更改列表项中 imageButton 的背景
trying to change background of imageButton in List item
Objective
我想在单击带有显示播放暂停(2 个图像)资源的 ImageButton(最初隐藏,单击时可见)的列表项时播放声音。
ImageButton只是为了向用户显示声音状态。
问题
当我滚动列表时,imageButton 再次消失。
代码
基础适配器
private class ListAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater mInflater;
ViewHolder holder;
ListAdapter(Context context) {
mContext = context;
this.mInflater = LayoutInflater.from(mContext);
}
@Override
public int getCount() {
return indexTitles.size();
}
@Override
public Object getItem(int position) {
return indexTitles.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.dua_row, null);
holder.mainBg = (RelativeLayout) convertView.findViewById(R.id.duaBG);
holder.title_text = (TextView) convertView.findViewById(R.id.title_text);
holder.buttonPlayPause = (ImageButton) convertView.findViewById(R.id.imageButton);
holder.buttonPlayPause.setFocusable(false);
holder.buttonPlayPause.setFocusableInTouchMode(false);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
String leftRemoved = indexTitles.get(position).trim();
holder.title_text.setText(leftRemoved);
// /player selection
if (playPos == position) {
holder.buttonPlayPause.setBackgroundResource(R.drawable.buttonpause);
holder.mainBg.setBackgroundColor(Color.parseColor("#000000"));
holder.title_text.setTextColor(Color.parseColor("#D59D52"));
} else {
holder.buttonPlayPause.setVisibility(View.GONE);
holder.title_text.setTextColor(Color.parseColor("#000000"));
holder.mainBg.setBackgroundColor(Color.parseColor("#D59D52"));
}
return convertView;
}
列表行
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
android:id="@+id/duaBG"
android:background="#D59D52">
<TextView
android:layout_width="match_parent"
android:layout_height="32dp"
android:text=""
android:textSize="18dp"
android:id="@+id/title_text"
android:ellipsize="end"
android:maxLines="1"
android:layout_alignParentTop="true"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/activity_horizontal_margin"
android:layout_marginBottom="@dimen/activity_horizontal_margin"
android:layout_toLeftOf="@+id/imageButton"
android:layout_toStartOf="@+id/imageButton" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton"
android:focusable="false"
android:visibility="gone"
android:background="@drawable/buttonpause"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="5dp"
android:background="#000000"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"></LinearLayout>
OnItemClickListener
// indexTitles is ArrayList<String>
indexTitles = getIndexTitles();
final ListAdapter adapter = new ListAdapter(this);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final View v = view.findViewById(R.id.imageButton);
v.setVisibility(View.VISIBLE);
if (mediaPlayer.isPlaying() && playPos == position) {
// pause mediaplayer
mediaPlayer.pause();
MEDIA_PAUSED = true;
v.setBackgroundResource(R.drawable.buttonplay);
} else if (MEDIA_PAUSED && !mediaPlayer.isPlaying() && playPos == position) {
MEDIA_PAUSED = false;
mediaPlayer.start();
v.setBackgroundResource(R.drawable.buttonpause);
} else if (!mediaPlayer.isPlaying() || mediaPlayer.isPlaying() && playPos != position) {
// release and start from this position
mediaPlayer.reset();
v.setVisibility(View.VISIBLE);
v.setBackgroundResource(R.drawable.buttonpause);
String s = String.format("%03d", position + 2);
String Path = SDCARD_PATH + "/DoaData/DD_" + s + ".mp3";
playPos = position;
adapter.notifyDataSetChanged();
File file = new File(Path);
Uri uri = Uri.fromFile(file);
try {
mediaPlayer.setDataSource(context, uri);
mediaPlayer.prepare();
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
v.setBackgroundResource(R.drawable.buttonplay);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
需要什么
我想让 imageButton 保持其播放或暂停状态。
谢谢
只需在 IF 语句中设置可见性,如下所示:
if (playPos == position) {
holder.buttonPlayPause.setVisibility(View.VISIBLE);
// further implementation
} else {
holder.buttonPlayPause.setVisibility(View.GONE);
// further implementation
}
出现问题,因为列表适配器回收旧视图。当一个视图不可见并且列表正在使用旧视图创建新视图时,您必须再次设置每个不同的 属性,否则前一个视图对象的所有属性都是 recycled/reused.
在@Thomas 和@shayan 的帮助下,我已经做到了
这就是我更改代码以获得所需内容的方式
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.dua_row, null);
holder.mainBg = (RelativeLayout) convertView.findViewById(R.id.duaBG);
holder.title_text = (TextView) convertView.findViewById(R.id.title_text);
holder.buttonPlayPause = (ImageButton) convertView.findViewById(R.id.imageButton);
holder.buttonPlayPause.setFocusable(false);
holder.buttonPlayPause.setFocusableInTouchMode(false);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
String leftRemoved = indexTitles.get(position).trim();
holder.title_text.setText(leftRemoved);
// /player selection
if (playPos == position) {
if(MEDIA_PAUSED){
holder.buttonPlayPause.setBackgroundResource(R.drawable.buttonplay);
} else if(!MEDIA_PAUSED) {
holder.buttonPlayPause.setBackgroundResource(R.drawable.buttonpause);
}
holder.mainBg.setBackgroundColor(Color.parseColor("#000000"));
holder.title_text.setTextColor(Color.parseColor("#D59D52"));
holder.buttonPlayPause.setVisibility(View.VISIBLE);
} else {
holder.buttonPlayPause.setVisibility(View.GONE);
holder.title_text.setTextColor(Color.parseColor("#000000"));
holder.mainBg.setBackgroundColor(Color.parseColor("#D59D52"));
}
return convertView;
}
并像这样更改了 onItemClick()
try {
mediaPlayer.setDataSource(context, uri);
mediaPlayer.prepare();
mediaPlayer.start();
MEDIA_PAUSED = false;
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
v.setBackgroundResource(R.drawable.buttonplay);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
});
Objective
我想在单击带有显示播放暂停(2 个图像)资源的 ImageButton(最初隐藏,单击时可见)的列表项时播放声音。 ImageButton只是为了向用户显示声音状态。
问题
当我滚动列表时,imageButton 再次消失。
代码
基础适配器
private class ListAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater mInflater;
ViewHolder holder;
ListAdapter(Context context) {
mContext = context;
this.mInflater = LayoutInflater.from(mContext);
}
@Override
public int getCount() {
return indexTitles.size();
}
@Override
public Object getItem(int position) {
return indexTitles.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.dua_row, null);
holder.mainBg = (RelativeLayout) convertView.findViewById(R.id.duaBG);
holder.title_text = (TextView) convertView.findViewById(R.id.title_text);
holder.buttonPlayPause = (ImageButton) convertView.findViewById(R.id.imageButton);
holder.buttonPlayPause.setFocusable(false);
holder.buttonPlayPause.setFocusableInTouchMode(false);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
String leftRemoved = indexTitles.get(position).trim();
holder.title_text.setText(leftRemoved);
// /player selection
if (playPos == position) {
holder.buttonPlayPause.setBackgroundResource(R.drawable.buttonpause);
holder.mainBg.setBackgroundColor(Color.parseColor("#000000"));
holder.title_text.setTextColor(Color.parseColor("#D59D52"));
} else {
holder.buttonPlayPause.setVisibility(View.GONE);
holder.title_text.setTextColor(Color.parseColor("#000000"));
holder.mainBg.setBackgroundColor(Color.parseColor("#D59D52"));
}
return convertView;
}
列表行
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
android:id="@+id/duaBG"
android:background="#D59D52">
<TextView
android:layout_width="match_parent"
android:layout_height="32dp"
android:text=""
android:textSize="18dp"
android:id="@+id/title_text"
android:ellipsize="end"
android:maxLines="1"
android:layout_alignParentTop="true"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/activity_horizontal_margin"
android:layout_marginBottom="@dimen/activity_horizontal_margin"
android:layout_toLeftOf="@+id/imageButton"
android:layout_toStartOf="@+id/imageButton" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton"
android:focusable="false"
android:visibility="gone"
android:background="@drawable/buttonpause"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="5dp"
android:background="#000000"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"></LinearLayout>
OnItemClickListener
// indexTitles is ArrayList<String>
indexTitles = getIndexTitles();
final ListAdapter adapter = new ListAdapter(this);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final View v = view.findViewById(R.id.imageButton);
v.setVisibility(View.VISIBLE);
if (mediaPlayer.isPlaying() && playPos == position) {
// pause mediaplayer
mediaPlayer.pause();
MEDIA_PAUSED = true;
v.setBackgroundResource(R.drawable.buttonplay);
} else if (MEDIA_PAUSED && !mediaPlayer.isPlaying() && playPos == position) {
MEDIA_PAUSED = false;
mediaPlayer.start();
v.setBackgroundResource(R.drawable.buttonpause);
} else if (!mediaPlayer.isPlaying() || mediaPlayer.isPlaying() && playPos != position) {
// release and start from this position
mediaPlayer.reset();
v.setVisibility(View.VISIBLE);
v.setBackgroundResource(R.drawable.buttonpause);
String s = String.format("%03d", position + 2);
String Path = SDCARD_PATH + "/DoaData/DD_" + s + ".mp3";
playPos = position;
adapter.notifyDataSetChanged();
File file = new File(Path);
Uri uri = Uri.fromFile(file);
try {
mediaPlayer.setDataSource(context, uri);
mediaPlayer.prepare();
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
v.setBackgroundResource(R.drawable.buttonplay);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
需要什么 我想让 imageButton 保持其播放或暂停状态。
谢谢
只需在 IF 语句中设置可见性,如下所示:
if (playPos == position) {
holder.buttonPlayPause.setVisibility(View.VISIBLE);
// further implementation
} else {
holder.buttonPlayPause.setVisibility(View.GONE);
// further implementation
}
出现问题,因为列表适配器回收旧视图。当一个视图不可见并且列表正在使用旧视图创建新视图时,您必须再次设置每个不同的 属性,否则前一个视图对象的所有属性都是 recycled/reused.
在@Thomas 和@shayan 的帮助下,我已经做到了
这就是我更改代码以获得所需内容的方式
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.dua_row, null);
holder.mainBg = (RelativeLayout) convertView.findViewById(R.id.duaBG);
holder.title_text = (TextView) convertView.findViewById(R.id.title_text);
holder.buttonPlayPause = (ImageButton) convertView.findViewById(R.id.imageButton);
holder.buttonPlayPause.setFocusable(false);
holder.buttonPlayPause.setFocusableInTouchMode(false);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
String leftRemoved = indexTitles.get(position).trim();
holder.title_text.setText(leftRemoved);
// /player selection
if (playPos == position) {
if(MEDIA_PAUSED){
holder.buttonPlayPause.setBackgroundResource(R.drawable.buttonplay);
} else if(!MEDIA_PAUSED) {
holder.buttonPlayPause.setBackgroundResource(R.drawable.buttonpause);
}
holder.mainBg.setBackgroundColor(Color.parseColor("#000000"));
holder.title_text.setTextColor(Color.parseColor("#D59D52"));
holder.buttonPlayPause.setVisibility(View.VISIBLE);
} else {
holder.buttonPlayPause.setVisibility(View.GONE);
holder.title_text.setTextColor(Color.parseColor("#000000"));
holder.mainBg.setBackgroundColor(Color.parseColor("#D59D52"));
}
return convertView;
}
并像这样更改了 onItemClick()
try {
mediaPlayer.setDataSource(context, uri);
mediaPlayer.prepare();
mediaPlayer.start();
MEDIA_PAUSED = false;
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
v.setBackgroundResource(R.drawable.buttonplay);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
});