这个想法是我想从listView中的sdcard显示mp3文件的列表,每行还包含一个带有三个项目的旋转器(共享,重命名和删除(,我使用自定义阵列arrayadapter for这个目的,我一直坚持如何在自定义Arrayadapter类上添加旋转器
这是activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:theme="@style/AppTheme"
tools:context=".MainActivity"
>
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="416dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="0dp" />
<Button
android:id="@+id/stopBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
android:layout_marginBottom="28dp"
android:text="Stop" />
</LinearLayout>
这是我创建旋转器
的地方<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:paddingLeft="14dp"
>
<TextView
android:id="@+id/text1"
android:layout_width="0dp"
android:layout_height="33dp"
android:layout_weight="1"
android:gravity="center|start"
/>
<Spinner
android:id="@+id/spinner"
android:layout_width="31dp"
android:layout_height="33dp"
android:layout_gravity="right"
android:background="@drawable/download"
>
</Spinner>
</LinearLayout>
在这里我创建数据类型
public class MyDataType {
// Name of the song
private String mSongName;
// Drawable Menu resource ID
private int mSpinner;
/** Audio resource ID for the word */
//private int mAudioResourceId;
//public MyDataType(String vName, int imageResourceId, int audioResourceId){
public MyDataType(String vName, int spinner){
mSongName = vName;
mSpinner = spinner;
//mAudioResourceId = audioResourceId;
}
public String getSongName() {
return mSongName;
}
public int getSpinner() {
return mSpinner;
}
}
在这里我创建自定义适配器
public class SongAdapter extends ArrayAdapter<MyDataType> {
public SongAdapter(Context context, ArrayList<MyDataType> words) {
super(context, 0, words);
}
Spinner mSpinner;
ArrayAdapter<CharSequence> mAdapter;
@Override
public View getView(int position, View convertView, ViewGroup parent) {
MyDataType currentSong = getItem(position);
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(R.layout.song_list, parent, false);
}
TextView songTextView = (TextView)
listItemView.findViewById(R.id.text1);
songTextView.setText(currentSong.getSongName());
mSpinner = (Spinner) listItemView.findViewById(R.id.spinner);
return listItemView;
}
}
这是主要活动
public class MainActivity extends AppCompatActivity {
private static final String SD_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Xylophone/";
ArrayList<MyDataType> file_list = new ArrayList<MyDataType>();
private final ArrayList<String> songs = new ArrayList<String>();
private MediaPlayer mp = new MediaPlayer();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MediaPlayer mp = new MediaPlayer();
//updatePlayList();
if (ActivityCompat.checkSelfPermission(this,
android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
fillList();
} else {
ActivityCompat.requestPermissions(this, new String[] {android.Manifest.permission.READ_EXTERNAL_STORAGE}, 100);
}
final SongAdapter adapter = new SongAdapter(this, file_list);
ListView listView = (ListView) findViewById(R.id.list);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
try{
mp.reset();
mp.setDataSource(SD_PATH + songs.get(position));
mp.prepare();
mp.start();
}catch (IOException e){
Log.v(getString(R.string.app_name),e.getMessage() );
}
}
});
Button stopPlay = (Button) findViewById(R.id.stopBtn);
stopPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mp.stop();
}
});
}
private void fillList() {
File file = new File(SD_PATH );
File list[] = file.listFiles();
for (int i = 0; i < list.length; i++) {
//file_list.add(list[i].getName(),);
songs.add(list[i].getName());
MyDataType myList = new MyDataType(list[i].getName(), R.id.spinner);
file_list.add(myList);
}
}
}
cotain菜单项的字符串值
<resources>
<string name="app_name">PlayMp3List</string>
<string-array name="spinner_data">
<item>Rename</item>
<item>Delete</item>
<item>Share</item>
</string-array>
</resources>
好吧,看来您几乎拥有所需的所有东西。但是,在此之前,您需要进行一些较小的更改。首先,在您查看权限的代码中,如果授予权限,您可以致电FillList((。但是在其他条件下,您请求许可。在上面的代码中,您没有显示如何处理许可请求结果。如果请求后授予许可,则在这种情况下,您也必须在此调用Filllist((。而且,在此致电FillList((之后,您还需要重新创建SongAdapter,并在列表视图上重做SetAdapter。
在filllist((中,您正在用歌曲标题和旋转器的ID初始化myList项目。你不应该这样做。您应该做的是用旋转器的"值"填充myList项目...默认值可能为0。
在自定义适配器中的getView((方法中,您正在根据位置参数获取当前项目,并将歌曲标题放入文本视图中。然后,您将获得对旋转器的引用,但是您没有做任何事情。获得参考后,您应该做类似mspinner.value = currentsong.getSpinner((;
之类的事情您想在myDatatype类中要做的是存储旋转器的值,而不是对旋转器本身的任何引用。您还需要某种单击事件,因此如果用户更改行中的旋转器的值,则可以使用新值更新ArrayList。假设用户可以更改选定的旋转器项目,如果不是,那么当您创建列表时,您必须弄清楚用什么值设置每个歌曲的旋转器值,而您不做的。
您的适配器代码应该看起来像这样。注意删除getContext((。
public class SongAdapter extends ArrayAdapter<MyDataType> {
Context mContext = null;
public SongAdapter(Context context, ArrayList<MyDataType> words) {
super(context, 0, words);
mContext = context;
}
Spinner mSpinner;
ArrayAdapter<CharSequence> mAdapter;
@Override
public View getView(int position, View convertView, ViewGroup parent) {
MyDataType currentSong = getItem(position);
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(mContext.inflate(R.layout.song_list, parent, false);
}
TextView songTextView = (TextView)
listItemView.findViewById(R.id.text1);
songTextView.setText(currentSong.getSongName());
mSpinner = (Spinner) listItemView.findViewById(R.id.spinner);
mSpinner.value = currentSong.getSpinner();
return listItemView;
}
}
在您的列表项中,单击方法您需要设置一个断点,以查看您在MP.SetDataSource中传递的路径是有效的路径。您的SD_Path可能在最后需要'/'。
在您的layout.xml文件中,您会这样定义旋转器:
<Spinner
android:id="@+id/spinner1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/country_arrays"
android:prompt="@string/country_prompt" />
条目 @array/country_arrays指向您在strings.xml中定义的列表
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">MyAndroidApp</string>
<string name="country_prompt">Choose a country</string>
<string-array name="country_arrays">
<item>Malaysia</item>
<item>United States</item>
<item>Indonesia</item>
<item>France</item>
<item>Italy</item>
<item>Singapore</item>
<item>New Zealand</item>
<item>India</item>
</string-array>
</resources>
您缺少Spinner XML定义中的值:
<Spinner
android:id="@+id/spinner"
android:layout_width="31dp"
android:layout_height="33dp"
android:layout_gravity="right"
android:background="@drawable/download"
android:entries="@array/spinner_data"
>
</Spinner>