12 Assets

为何使用assets

resource资源可以存储声音文件,可以通过ID来获取它。将类似的声音文件存储为资源后,我们就可以按特定的方式使用它们了,如根据设备的语言及系统版本调用不同的声音资源。

如果使用Android资源系统一个个去处理,效率会很低。assets可以看作随应用打包的微型文件系统,支持任意层次的文件目录结构。


创建BeatBox应用

创建布局文件

主布局文件fragment_beat_box.xml用于生成RecyclerView布局。

<androidx.recyclerview.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_beat_box_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

声音按钮布局文件list_item_sound.xml用于RecyclerView的列表项,作为列表项的按钮显示。

<Button
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/list_item_sound_button"
    android:layout_width="match_parent"
    android:layout_height="120dp"
    tools:text="声音名">
</Button>

实例化布局文件

BeatBoxFragment.java

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_beat_box, container, false);

    RecyclerView recyclerView = view.findViewById(R.id.fragment_beat_box_recycler_view);
    recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 3));
    recyclerView.setAdapter(new SoundAdapter(mBeatBox.getSounds()));

    return view;
}

创建SoundHolder

创建一个使用list_item_sound.xml布局的ViewHolder。

BeatBoxFragment.java

private class SoundHolder extends RecyclerView.ViewHolder {
    private Button mButton;
    private Sound mSound;

    public SoundHolder(LayoutInflater layoutInflater, ViewGroup container) {
        super(layoutInflater.inflate(R.layout.list_item_sound, container, false));

        mButton = itemView.findViewById(R.id.list_item_sound_button);
    }

    //绑定sound
    public void bindSound(Sound sound) {
        mSound = sound;
        mButton.setText(mSound.getName());
    }
}

创建SoundAdapter

创建一个绑定了SoundHolder的Adapter。

BeatBoxFragment.java

private class SoundAdapter extends RecyclerView.Adapter<SoundHolder> {
    private List<Sound> mSounds;

    public SoundAdapter(List<Sound> sounds) {
        mSounds = sounds;
    }

    @NonNull
    @Override
    public SoundHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(getActivity());
        return new SoundHolder(inflater, parent);
    }

    @Override
    public void onBindViewHolder(@NonNull SoundHolder soundHolder, int position) {
        Sound sound = mSounds.get(position);
        soundHolder.bindSound(sound);
        Log.d(TAG, "绑定了第 " + position + " 个sound...");
    }

    @Override
    public int getItemCount() {
        return mSounds.size();
    }
}

使用SoundAdapter

BeatBoxFragment.java

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    //...
    recyclerView.setAdapter(new SoundAdapter(mBeatBox.getSounds()));
    return view;
}

填充BeatBoxActivity

SingleFragmentActivity.java

public abstract class SingleFragmentActivity extends AppCompatActivity {
    protected abstract Fragment createFragment();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment);

        FragmentManager fm = getSupportFragmentManager();
        Fragment fragment = fm.findFragmentById(R.id.fragment_container);

        if (fragment == null) {
            fragment = createFragment();
            /**
             * 创建一个新的fragment事务,加入一个添加操作,然后提交该事务
             */
            fm.beginTransaction().add(R.id.fragment_container, fragment).commit();
        }
    }
}

BeatBoxActivity.java

public class BeatBoxActivity extends SingleFragmentActivity {
    @Override
    protected Fragment createFragment() {
        return BeatBoxFragment.newInstance();
    }
}

导入assets

  1. 右键单击app模块,选择New => Folder => Assets Folder,清楚Change Folder Location选项,保持Target Source Set选项为main;
  2. 然后右键单击assets目录,选择New => Directory,创建sample_sounds子目录,将声音资源文件复制到此目录。

处理assets

创建BeatBox类

BeatBox.java

public class BeatBox {
    private static final String TAG = "BeatBox";
    private static final String SOUNDS_FOLDER = "sample_sounds";

    private AssetManager mAssets;
    private List<Sound> mSounds = new ArrayList<>();

    public BeatBox(Context context) {
        mAssets = context.getAssets();
        loadSounds();
    }

    //获取asset资源
    private void loadSounds() {
        String[] soundNames;

        try {
            //取得assets中的资源清单
            soundNames = mAssets.list(SOUNDS_FOLDER);
            Log.i(TAG, "取得 " + soundNames.length + " 个声音资源。");
        }
        catch (IOException ioe) {
            Log.e(TAG, "无法取得assets资源清单。");
            return;
        }

        for (String filename : soundNames) {
            String assetPath = SOUNDS_FOLDER + "/" + filename;
            Sound sound = new Sound(assetPath);
            mSounds.add(sound);
        }
    }

    public List<Sound> getSounds() {
        return mSounds;
    }
}

在访问assets时,可以不用关心究竟是用哪个Context对象。而且在实际开发的任何场景下,所有context中的AssetManager管理的都是同一套assets资源。

可以使用AssetsManager.list(String)方法列出指定目录中的所有文件名。

创建BeatBox实例

BeatBoxFragment.java

private BeatBox mBeatBox;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mBeatBox = new BeatBox(getActivity());
}

使用assets

创建Sound对象

Sound.java

public class Sound {
    private String mAssetPath;
    private String mName;

    public Sound(String assetPath) {
        mAssetPath = assetPath;
        String[] components = assetPath.split("/");
        String filename = components[components.length - 1];
        mName = filename.replace(".wav", "");
    }

    public String getAssetPath() {
        return mAssetPath;
    }

    public String getName() {
        return mName;
    }
}

创建Sound列表

创建Sound类之后,就可以在BeatBox类中创建并初始化Sound列表(见「导入assets」)。

绑定Sound

在SoundHolder中添加代码绑定Sound(见「创建SoundHolder」)。

绑定Sound列表

让SoundAdapter与Sound数组关联起来(见「创建SoundAdapter」)。

设置Adapter

最后,在onCreateView(…)方法中传入BeatBox声音资源(见「使用SoundAdapter」)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值