In this page you can find info about:
- How to build a card with a LinearList
- Init the CardHeader
- Init the Card
- Init the Children
- Define the layout used by items
- Setup child view
- How to customize the divider
- Empty View
- How to disable the empty view
- How to customize the Empty View
- Using a custom inner layout
- ProgressBar
- How to enable the progressbar
- How to customize the ProgressBar
- Using a custom inner layout
The card with a LinearList inside is a particular Card
that can display items inside the Card
.
Technically it is a special LinearLayout
that works with an ArrayAdapter, so you can use your Card
inside a ScrollView
for example.
First, you need an XML layout that will display the Card
.
<it.gmariotti.cardslib.library.view.CardView
android:id="@+id/carddemo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:layout_marginTop="12dp"/>
Then create a model.
In this case you have to extend the CardWithList
(which extends Card
) and implement the required methods.
public class GoogleNowWeatherCard extends CardWithList {
public GoogleNowWeatherCard(Context context) {
super(context);
}
}
You have to specify your CardHeader
using the method initCardHeader()
.
It is a normal CardHeader
, with all its features.
@Override
protected CardHeader initCardHeader() {
//Add Header
CardHeader header = new CardHeader(getContext());
//Add a popup menu. This method set OverFlow button to visible
header.setPopupMenu(R.menu.popup_item, new CardHeader.OnClickCardHeaderPopupMenuListener() {
@Override
public void onMenuItemClick(BaseCard card, MenuItem item) {
switch (item.getItemId()){
case R.id.action_add:
WeatherObject w1= new WeatherObject(MyCard.this);
w1.city ="Madrid";
w1.temperature = 24;
w1.weatherIcon = R.drawable.ic_action_sun;
w1.setObjectId(w1.city);
mLinearListAdapter.add(w1);
break;
case R.id.action_remove:
mLinearListAdapter.remove(mLinearListAdapter.getItem(0));
break;
}
}
});
header.setTitle("Weather"); //should use R.string.
return header;
}
In this method you can customize your Card
with its features.
For example:
@Override
protected void initCard() {
setSwipeable(true);
setOnSwipeListener(new OnSwipeListener() {
@Override
public void onSwipe(Card card) {
Toast.makeText(getContext(), "Swipe on " + card.getCardHeader().getTitle(), Toast.LENGTH_SHORT).show();
}
});
}
You have to initialize your items inside the Card
using the method initChildren()
.
@Override
protected List<ListObject> initChildren() {
List<ListObject> mObjects = new ArrayList<ListObject>();
WeatherObject w1= new WeatherObject(this);
w1.city ="London";
w1.temperature = 16;
w1.weatherIcon = R.drawable.ic_action_cloud;
w1.setObjectId(w1.city);
mObjects.add(w1);
return mObjects;
}
If the list is empty you can return null
.
Each element in the list has to be a ListObject
.
To achieve it you can use two ways:
- extending the
DefaultListObject
class - implementing the
ListObject
interface.
In particular you can :
- set the item id (it can be very useful to identify the item in the list) with
setObjectId()
method. - set an
onItemClickListener
to register a callback for click on the single item.
setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(LinearListView parent, View view, int position, ListObject object) {
Toast.makeText(getContext(), "Click on " + getObjectId(), Toast.LENGTH_SHORT).show();
}
});
- set the single item as swipeable using
setSwipeable
item.setSwipeable(true);
- set an
OnItemSwipeListener
to register a callback for swipe on the single item.
item.setOnItemSwipeListener(new OnItemSwipeListener() {
@Override
public void onItemSwipe(ListObject object,boolean dismissRight) {
Toast.makeText(getContext(), "Swipe on " + object.getObjectId(), Toast.LENGTH_SHORT).show();
}
});
You can customize the background behind the items cloning this color in your project:
<!-- Used by card with list -->
<color name="card_base_cardwithlist_background_list_color">#10000000</color>
Otherwise you can customize this style in your project:
<!-- Style for card with list -->
<style name="cardwithlist">
<item name="android:background">@color/card_base_cardwithlist_background_list_color</item>
</style>
and finally you can provide your custom inner layout
You have to specify the layout used by each item. You have to implement this method:
@Override
public int getChildLayoutId() {
return R.layout.carddemo_googlenowweather_inner_main;
}
After declaring the layout used by items, you have to setup the elements inside the item binding it with the ListObject
.
@Override
public View setupChildView(int childPosition, ListObject object, View convertView, ViewGroup parent) {
TextView city = (TextView) convertView.findViewById(R.id.carddemo_weather_city);
ImageView icon = (ImageView) convertView.findViewById(R.id.carddemo_weather_icon);
TextView temperature = (TextView) convertView.findViewById(R.id.carddemo_weather_temperature);
WeatherObject weatherObject= (WeatherObject)object;
icon.setImageResource(weatherObject.weatherIcon);
city.setText(weatherObject.city);
temperature.setText(weatherObject.temperature + weatherObject.temperatureUnit);
return convertView;
}
You can customize the divider used by the List.
You can override this dimension in your project to change the height of divider.
<dimen name="card_base_cardwithlist_dividerHeight">1dp</dimen>
You can change the color of the divider cloning this color in your project:
<!-- Used by card with list -->
<color name="card_base_cardwithlist_divider_color">#E5E5E5</color>
Finally you can clone this style in your project:
<!-- Style for card with list -->
<style name="cardwithlist">
<item name="android:layout_marginTop">@dimen/card_base_cardwithlist_list_margin_top</item>
<item name="android:layout_marginLeft">@dimen/card_base_cardwithlist_list_margin_left</item>
<item name="android:divider">@color/card_base_cardwithlist_divider_color</item>
<item name="android:showDividers">middle</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">match_parent</item>
<item name="android:background">@color/card_base_cardwithlist_background_list_color</item>
</style>
The default card provides a built-in feature with an EmptyView as you can find in the standard ListView
.
This feature is enabled by default but you can customize it.
The default view used is a TextView
.
To disable the EmptyView you can use setUseEmptyView(false)
Example:
@Override
protected void initCard() {
setUseEmptyView(false);
}
You can customize the emptyView in different ways:
You can change the string simply overriding this string in your project:
<string name="card_empty_cardwithlist_text">No data....</string>
The default layout inner_base_main_cardwithlist uses a ViewStub
.
You can dynamically change the the layout resource to inflate when the ViewStub becomes visible, using the method setEmptyViewViewStubLayoutId
.
Example:
@Override
protected void initCard() {
setEmptyViewViewStubLayoutId(R.layout.carddemo_extras_base_withlist_empty);
}
Of course you can provide a complete different view using a custom innerlayout for your card. In this you can use your favorite View.
The default card provides a built-in feature with a ProgressBar that can be displayed inside the CardView
.
This feature is disabled by default but you can customize it.
The default view used is a ProgressBar
and a TextView.
To enable the ProgressBar you can use setUseProgressBar(true)
Example:
@Override
protected void initCard() {
setUseProgressBar(true);
}
You can display the ProgressBar using this code:
card.updateProgressBar(false,false);
The first parameter indicates to hide the list and display the progressbar, while the second parameter indicates if you want to animate the transition between the views. When the process is ended you can hide the ProgressBar and display the list using:
card.updateProgressBar(true,true);
You can customize the ProgressBar in different ways:
You can change the string used simply overriding this string in your project:
<string name="card_progressbar_cardwithlist_text"></string>
The default layout inner_base_main_cardwithlist uses a ViewStub
.
You can dynamically change the the layout resource to inflate when the ViewStub becomes visible, using the method setProgressBarViewStubLayoutId
.
Example:
@Override
protected void initCard() {
setProgressBarViewStubLayoutId(R.layout.carddemo_extras_base_withlist_progressbar);
}
Of course you can provide a complete different view using a custom innerlayout for your card. In this you can use your favorite View.
As other cards you can use a custom inner layout instead of the default layout. You can set it in your constructor for example:
public WeatherCard(Context context) {
super(context,R.layout.carddemo_extras_inner_base_main_cardwithlist);
}
Your layout have to provide an element with `
<it.gmariotti.cardslib.library.prototypes.LinearListView
android:id="@+id/card_inner_base_main_cardwithlist"
/>
Also your layout can provide a EmptyView element. It is not mandatory.
Pay attention to ids. If you use the same original ids, all built-in features are preserved. You can use your custom ids. In this case you have to set them in this way:
@Override
protected void initCard() {
setListViewId(R.id.yourListId);
setEmptyViewId(R.id.yourEmptyViewId);
}
Also you can add other elements inside you layout. In this case you have to set them with the method
setupInnerViewElements
. In this case it is very important to call the super method.
@Override
public void setupInnerViewElements(ViewGroup parent, View view) {
//It is very important call the super method!!
super.setupInnerViewElements(parent, view);
//Your elements
}