+++
date = "2016-07-16T17:21:28+02:00"
title = "Custom item layout"
[menu]
[menu.main]
identifier = "custom_item_layout"
url = "example/custom_item_layout/"
parent = "Examples"
weight = 20
+++
Say you want to browse some files which have really long names. By default, filenames will be cut if they exceed one line in width like `ThisIsAReallyLongFi...`. What if we really wanted it show like in this image?

The behavior of the text is defined in the listitem layouts:
[nnf_filepicker_listitem_checkable](https://github.com/spacecowboy/NoNonsense-FilePicker/blob/master/library/src/main/res/layout/nnf_filepicker_listitem_checkable.xml)
and
[nnf_filepicker_listitem_dir](https://github.com/spacecowboy/NoNonsense-FilePicker/blob/master/library/src/main/res/layout/nnf_filepicker_listitem_dir.xml).
There are two kinds of layouts, one with a checkbox to allow selection, and one without a checkbox. The second one is also used for the special header item `..` though you could of course have a special layout for that if you wanted.
### Layouts
Let's create some new layouts which will support longer filenames as follows:
**longer_listitem_checkable.xml**
```xml
```
**longer_listitem_dir.xml**
```xml
```
Note that I defined the TextViews to have a maximum of 4 lines (actual number is up to you), and a minimum height of `android:listPreferredItemHeight` (this I recommend, otherwise it looks wonky and off-center). And just be clear, the *ids* of these fields must be `@+id/item_icon`, `@android:id/text1`, and `@+id/checkbox`, or the code WILL crash on you.
### Code
To use the new layouts, you need to override the `onCreateViewHolder` method in
[AbstractFilePickerFragment](https://github.com/spacecowboy/NoNonsense-FilePicker/blob/master/library/src/main/java/com/nononsenseapps/filepicker/AbstractFilePickerFragment.java).
Since this example will be browsing the SD-card, I will extend from the built-in FilePickerFragment.
```java
public class CustomLayoutFilePickerFragment extends FilePickerFragment {
/**
* @param parent Containing view
* @param viewType which the ViewHolder will contain. Will be one of:
* [VIEWTYPE_HEADER, VIEWTYPE_CHECKABLE, VIEWTYPE_DIR]. It is OK, and even expected, to use the same
* layout for VIEWTYPE_HEADER and VIEWTYPE_DIR.
* @return a view holder for a file or directory (the difference is presence of checkbox).
*/
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
switch (viewType) {
case LogicHandler.VIEWTYPE_HEADER:
v = LayoutInflater.from(getActivity()).inflate(R.layout.longer_listitem_dir,
parent, false);
return new HeaderViewHolder(v);
case LogicHandler.VIEWTYPE_CHECKABLE:
v = LayoutInflater.from(getActivity()).inflate(R.layout.longer_listitem_checkable,
parent, false);
return new CheckableViewHolder(v);
case LogicHandler.VIEWTYPE_DIR:
default:
v = LayoutInflater.from(getActivity()).inflate(R.layout.longer_listitem_dir,
parent, false);
return new DirViewHolder(v);
}
}
}
```
And as always, to use your custom fragment you need a custom activity which loads it for you:
```java
public class CustomLayoutPickerActivity extends AbstractFilePickerActivity {
public CustomLayoutPickerActivity() {
super();
}
@Override
protected AbstractFilePickerFragment getFragment(
final String startPath, final int mode, final boolean allowMultiple,
final boolean allowCreateDir) {
// Load our custom fragment here
AbstractFilePickerFragment fragment = new CustomLayoutFilePickerFragment();
// startPath is allowed to be null. In that case, default folder should be SD-card and not "/"
fragment.setArgs(startPath != null ? startPath : Environment.getExternalStorageDirectory().getPath(),
mode, allowMultiple, allowCreateDir);
return fragment;
}
}
```