本章主要实现文件选择系统。 这个功能主要有两个类实现,一个是Fragment子类MusicFoldersSelectionFragment,一个是里面的ListView配套的Adapter的子类MultiselectListViewAdapter。
咱们先添加这两个类。 然后让他在MusicFoldersFragment里面的一个folders_fragment_holder控件显示的。
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mContext = getActivity().getApplicationContext();
mApp = (Common) mContext;
View rootView = inflater.inflate(R.layout.fragment_welcome_screen_2, container, false);
mFoldersLayout = (RelativeLayout) rootView.findViewById(R.id.folders_fragment_holder);
mFoldersLayout.setVisibility(View.VISIBLE);
mFoldersLayout.setEnabled(false);
mChildFragmentManager = this.getChildFragmentManager();
mChildFragmentManager.beginTransaction()
.add(R.id.folders_fragment_holder, getMusicFoldersSelectionFragment())
.commit();
return rootView;
}
/**
* Instantiates a new fragment if mMusicFoldersSelectionFragment is null.
* Returns the current fragment, otherwise.
*/
public MusicFoldersSelectionFragment getMusicFoldersSelectionFragment() {
if (mMusicFoldersSelectionFragment==null) {
mMusicFoldersSelectionFragment = new MusicFoldersSelectionFragment();
Bundle bundle = new Bundle();
bundle.putBoolean("com.jams.music.player.WELCOME", true);
mMusicFoldersSelectionFragment.setArguments(bundle);
}
return mMusicFoldersSelectionFragment;
}
这样就可以简单实现MusicFoldersSelectionFragment加载。我们开始为这个 文件显示工作了。
/**
* Created by kankan on 2016/5/26.
*/
public class MusicFoldersSelectionFragment extends Fragment {
private String TAG = this.getClass().getSimpleName();
private Context mContext;
private Common mApp;
private boolean mWelcomeSetup = false;
private RelativeLayout mUpLayout;
private ImageView mUpIcon;
private TextView mUpText;
private TextView mCurrentFolderText;
private ListView mFoldersListView;
private Cursor mCursor;
private String mRootDir;
private String mCurrentDir;
private List<String> mFileFolderNamesList;
private List<String> mFileFolderPathsList;
private List<String> mFileFolderSizesList;
private HashMap<String, Boolean> mMusicFolders;
private static boolean CALLED_FROM_WELCOME = false;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mContext = getActivity().getApplicationContext();
mApp = (Common) mContext;
View rootView = inflater.inflate(R.layout.fragment_folders_selection, container, false);
mMusicFolders = new HashMap<String, Boolean>();
mFoldersListView = (ListView) rootView.findViewById(R.id.folders_list_view);
mFoldersListView.setFastScrollEnabled(true);
mWelcomeSetup = getArguments().getBoolean("com.jams.music.player.WELCOME");
Log.i(TAG, "mWelcomSetup is "+ mWelcomeSetup);
mUpLayout = (RelativeLayout) rootView.findViewById(R.id.folders_up_layout);
mUpIcon = (ImageView) rootView.findViewById(R.id.folders_up_icon);
mUpText = (TextView) rootView.findViewById(R.id.folders_up_text);
mCurrentFolderText = (TextView) rootView.findViewById(R.id.folders_current_directory_text);
mUpText.setTypeface(TypefaceHelper.getTypeface(mContext, "Roboto-Regular"));
mCurrentFolderText.setTypeface(TypefaceHelper.getTypeface(mContext, "Roboto-Regular"));
mUpLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
getDir(new File(mCurrentDir).getParentFile().getCanonicalPath());
} catch (Exception e) {
e.printStackTrace();
}
}
});
mFoldersListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int index, long arg3) {
String newPath = mFileFolderPathsList.get(index);
Log.i(TAG, "path is " + newPath);
getDir(newPath);
}
});
mRootDir = Environment.getExternalStorageDirectory().getAbsolutePath().toString();
getDir(mRootDir);
return rootView;
}
void getDir(String dirPath){
mFileFolderNamesList = new ArrayList<String>();
mFileFolderPathsList = new ArrayList<String>();
mFileFolderSizesList = new ArrayList<String>();
/ TODO: 2016/5/27
int permissionCheck1 = ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_EXTERNAL_STORAGE);
int permissionCheck2 = ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permissionCheck1 != PackageManager.PERMISSION_GRANTED || permissionCheck2 != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE},
124);
}
getDirList(dirPath);
}
@Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions,
int[] grantResults) {
if (requestCode == 124) {
if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
getDirList(mRootDir);
}
}
}
private void setCurrentDirText() {
mCurrentFolderText.setText(mCurrentDir);
}
void getDirList(String dir){
File f =new File(dir);
File[] files = f.listFiles();
if (files!=null) {
Arrays.sort(files);
for (int i = 0; i < files.length; i++) {
File file = files[i];
if (!file.isHidden() && file.canRead()) {
if (file.isDirectory()) {
/*
* Starting with Android 4.2, /storage/emulated/legacy/...
* is a symlink that points to the actual directory where
* the user's files are stored. We need to detect the
* actual directory's file path here.
*/
String filePath;
filePath = file.getAbsolutePath();
// Log.i(TAG, "filePath is" + filePath);
mFileFolderPathsList.add(filePath);
mFileFolderNamesList.add(file.getName());
}
}
}
}
boolean dirChecked = false;
if(getmMusicFolders().get(dir) != null){
dirChecked = getmMusicFolders().get(dir);
}
MultiselectListViewAdapter mFoldersListViewAdapter = new MultiselectListViewAdapter(mContext,
this, mWelcomeSetup, dirChecked);
mFoldersListView.setAdapter(mFoldersListViewAdapter);
mFoldersListViewAdapter.notifyDataSetChanged();
mCurrentDir = dir;
setCurrentDirText();
}
public HashMap<String, Boolean> getmMusicFolders() {
return mMusicFolders;
}
public List<String> getFileFolderNamesList() {
return mFileFolderNamesList;
}
public List<String> getFileFolderPathsList() {
return mFileFolderPathsList;
}
}<span style="font-family:Arial, Helvetica, sans-serif;"><span style="white-space: normal;">
</span></span>
mFileFolderPathsList
这个类主要实现了加载ListView控件来显示文件系统列表。 其中用了一个HashMap的对象存储用户已经设置过的文件夹,mFileFolderPathsList用来存储当前目录下的文件系统。里面有添加了些关Android6.0动态权限管理而改动的代码。
最后一个是Adapter 子类,该类是用来显示每一个文件夹子项,并且让用户选择。
/**
* Created by kankan on 2016/5/27.
*/
public class MultiselectListViewAdapter extends ArrayAdapter<String> {
String TAG = this.getClass().getSimpleName();
private Context mContext;
private Common mApp;
private MusicFoldersSelectionFragment mFragment;
private boolean mDirChecked;
private boolean mWelcomeSetup;
public MultiselectListViewAdapter(Context context,
MusicFoldersSelectionFragment fragment,
boolean welcomeSetup,
boolean dirChecked) {
super(context, -1, fragment.getFileFolderNamesList());
mContext = context;
mApp = (Common) mContext.getApplicationContext();
mFragment = fragment;
mDirChecked = dirChecked; //Indicates if this entire dir is a music folder.
mWelcomeSetup = welcomeSetup;
}
private MultiselectListViewAdapter(Context context, int resource) {
super(context, resource);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
FoldersMultiselectHolder holder = null;
if(convertView == null){
convertView = LayoutInflater.from(mContext)
.inflate(R.layout.folder_view_layout_multiselect,parent, false);
holder = new FoldersMultiselectHolder();
holder.fileFolderNameText = (TextView) convertView.findViewById(R.id.file_folder_title_multiselect);
holder.fileFolderNameText.setTextColor(Color.parseColor("#2F2F2F"));
holder.fileFoldersCheckbox = (CheckBox)convertView.findViewById(R.id.music_folder_select_checkbox);
convertView.setTag(holder);
}else {
holder = (FoldersMultiselectHolder) convertView.getTag();
}
holder.fileFoldersCheckbox.setTag(mFragment.getFileFolderPathsList().get(position));
if(mDirChecked){
holder.fileFoldersCheckbox.setChecked(true);
}else{
holder.fileFoldersCheckbox.setChecked(false);
}
holder.fileFolderNameText.setText(mFragment.getFileFolderNamesList().get(position));
//Set the checkbox status.
String folderPath = mFragment.getFileFolderPathsList().get(position);
if(mFragment.getmMusicFolders().get(folderPath) != null &&
mFragment.getmMusicFolders().get(folderPath) == true){
holder.fileFoldersCheckbox.setChecked(true);
}
holder.fileFoldersCheckbox.setOnCheckedChangeListener( checkedChangeListener);
return convertView;
}
private CompoundButton.OnCheckedChangeListener checkedChangeListener = new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton checkBox, boolean isChecked) {
if(checkBox.isPressed()){
String filePath = (String)checkBox.getTag();
if(isChecked){
mFragment.getmMusicFolders().put(filePath, true);
}else{
if(mFragment.getmMusicFolders().containsKey(filePath)){
removeKeyAndSubFolders(filePath);
}else {
mFragment.getmMusicFolders().put(filePath, false);
}
}
}
}
};
private void removeKeyAndSubFolders(String key){
Set<String> keySet = mFragment.getmMusicFolders().keySet();
String[] keyArray = new String[keySet.size()];
keySet.toArray(keyArray);
//tests
String[] keyArray2 =(String[]) keySet.toArray();
Log.i(TAG, Arrays.toString(keyArray2));
if(keyArray == null || keyArray.length == 0){
return;
}
for(int i = 0; i <keyArray.length; i++){
if(keyArray[i].startsWith(key))
mFragment.getmMusicFolders().remove(keyArray[i]);
}
}
static class FoldersMultiselectHolder {
public TextView fileFolderNameText;
public TextView fileFolderSizeText;
public CheckBox fileFoldersCheckbox;
public ImageView fileFoldersImage;
}
}
基本上就是重写getView方法,不多解释了。
最终效果图
源代码稍后上传!