I'm new in android..
I would like to create the different views in Listview using Custom Adapter.
Please suggest me how I can do this.
In first row there will be a single Item and in second row there will be two item and so on..
Please Check the attached screen..
Thanks in advance
Define a custom layout of how you want the list row like this
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="#dimen/headerHeightCustRow"
android:background="#FFFFFF"
tools:ignore="HardcodedText" >
<TextView
android:id="#+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dip"
android:layout_marginLeft="#dimen/viewSpace1"
android:text="Varun Mad"
android:textSize="#dimen/logout_textSize"
android:textStyle="bold"
android:textColor="#color/orange_normal" />
<TextView
android:id="#+id/txtCustId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginLeft="#dimen/viewSpace3"
android:layout_marginTop="#dimen/viewSpace3"
android:layout_marginRight="#dimen/viewSpace3"
android:text="10549"
android:layout_centerVertical="true"
android:textColor="#color/orange_normal"
android:textSize="15sp" />
<TextView
android:id="#+id/txtPhone"
android:layout_below="#id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/viewSpace1"
android:text="(886)677-8855"
android:textColor="#color/orange_normal"
android:textSize="#dimen/vsText" />
<TextView
android:id="#+id/txtEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/viewSpace1"
android:text="ggg#gmail.com"
android:textSize="#dimen/vsText"
android:layout_below="#id/txtPhone"
android:textColor="#color/orange_normal" />
<View
android:layout_width="fill_parent"
android:layout_height="0.5dip"
android:layout_alignParentBottom="true"
android:background="#color/greyDark" />
here is the adapter class
public class SearchCustomerAdapter extends BaseAdapter {
Context ctx;
LayoutInflater lInflater;
ArrayList<SearchCustomerItem> objects;
public SearchCustomerAdapter(Context context, ArrayList<SearchCustomerItem> products) {
ctx = context;
objects = products;
lInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return objects.size();
}
#Override
public Object getItem(int position) {
return objects.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = lInflater.inflate(R.layout.search_cust_row, parent, false);
}
SearchCustomerItem p = getProduct(position);
((TextView) view.findViewById(R.id.txtName)).setText(p.customerName);
if (p.customerEmail.compareTo("anyType{}") == 0) {
((TextView) view.findViewById(R.id.txtEmail)).setText("");
} else {
((TextView) view.findViewById(R.id.txtEmail)).setText(p.customerEmail);
}
((TextView) view.findViewById(R.id.txtPhone)).setText(p.customerPhone);
((TextView) view.findViewById(R.id.txtCustId)).setText(p.customerId);
return view;
}
SearchCustomerItem getProduct(int position) {
return ((SearchCustomerItem) getItem(position));
}
#SuppressWarnings("unused")
ArrayList<SearchCustomerItem> getBox() {
ArrayList<SearchCustomerItem> box = new ArrayList<SearchCustomerItem>();
for (SearchCustomerItem p : objects) {
// if (p.box)
// box.add(p);
}
return box;
}
}
and the ITem Class
public class SearchCustomerItem {
public String customerName;
public String customerPhone;
public String customerEmail;
public String customerId;
public SearchCustomerItem(String _cName, String _cPhone, String _cEmail, String _cCustId) {
customerName = _cName;
customerPhone = _cPhone;
customerEmail = _cEmail;
customerId = _cCustId;
}
}
you can initialize the adapter,
add the items in Arraylist and show in the list by using
SearchCustomerAdapter boxAdapter;
ArrayList<SearchCustomerItem> products = new ArrayList<SearchCustomerItem>();
to add items in arraylist
products.add(new SearchCustomerItem("CustomerName","PhoneNo","Cust_EmailId","Cust_Id"));
//Add as many items you want
than
boxAdapter = new SearchCustomerAdapter(SearchActivity.this, products);
list.setAdapter(boxAdapter);
This link might help you. link
You should do it step by step.
Extend Base Adapter class by you Custom Adapter class
Override getView and other related methods
set the adapter to list view adapter.
Related
i plan to have a list view which when onlongclick, will be able to select all the subrows/related rows.
Example
Input:
Long click on user name/age/birthday
Output:
Return the username, age and birthday.
Problem
Will only return the user name if you long click on it and not the age and birthday.
I didn't include the age and birthday value to be display in the toast cause the app will display an error and stop functioning.
Latest:
Have shown the Adapter and object class on 26th Nov17
Custom layout of list view
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Username:"
android:background="#FF2400"
android:textColor="#FFFFFF" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/text_user_name"
android:textColor="#FFFFFF"
android:background="#FF2400"
android:text="Username"
android:gravity="left"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Age:"
android:background="#FFFFFF"
android:textColor="#000000" />
<EditText
android:layout_width="match_parent"
android:layout_weight="0.5"
android:textColor="#000000"
android:layout_height="wrap_content"
android:id="#+id/text_user_age"
android:background="#FFFFFF"
android:text="Age"
android:gravity="left"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Birthday:"
android:background="#FFFFFF"
android:textColor="#000000" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:textColor="#000000"
android:background="#FFFFFF"
android:id="#+id/text_user_birthday"
android:text="Birthday"
android:gravity="left"/>
</LinearLayout>
</LinearLayout>
DataListActivity (Listview activity)
listview.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener(){
public boolean onItemLongClick(AdapterView<?> arg0, View v,
int index, long arg3)
{
AlertDialog.Builder builder = new AlertDialog.Builder(DataListActivity.this);
builder.setTitle("Notice");
builder.setMessage("Launching this missile will destroy the entire universe. Is this what you intended to do?");
final View clicklist = v;
final int position = index;
builder.setPositiveButton("Launch missile", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
String selname= ((EditText) clicklist.findViewById(R.id.text_user_name)).getText().toString();
// String selage= ((EditText) clicklist.findViewById(R.id.text_user_age)).getText().toString();
String selbirthday= ((EditText) clicklist.findViewById(R.id.text_user_birthday)).getText().toString();
Toast.makeText(DataListActivity.this,selname + selage + selbirthday,Toast.LENGTH_LONG).show();
}
});
builder.setNegativeButton("Cancel", null);
AlertDialog dialog = builder.create();
dialog.show();
return false;
}
});
LayoutAdapter
public class ListDataAdapter extends ArrayAdapter{
List list = new ArrayList();
static class LayoutHandler
{
TextView NAME,AGE,BIRTHDAY;
}
public ListDataAdapter(Context context, int resource) {
super(context, resource);
}
#Override
public void add (Object object)
{
super.add(object);
list.add(object);
}
#Override
public int getCount(){
return list.size();
}
#Override
public Object getItem(int position)
{
return list.get(position);
}
#Override
public View getView (int position, View convertView, ViewGroup parent){
View row = convertView;
LayoutHandler layoutHandler;
if (row==null)
{
LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.row_layout,parent,false);
layoutHandler = new LayoutHandler();
layoutHandler.NAME = (TextView) row.findViewById(R.id.text_user_name);
layoutHandler.AGE = (TextView) row.findViewById(R.id.text_user_age);
layoutHandler.BIRTHDAY = (TextView) row.findViewById(R.id.text_user_birthday);
}
else
{
layoutHandler = (LayoutHandler) row.getTag();
}
DataProvider dataProvider = (DataProvider) this.getItem(position);
layoutHandler.NAME.setText(dataProvider.getName());
layoutHandler.AGE.setText(dataProvider.getAge());
layoutHandler.BIRTHDAY.setBIRTHDAY(dataProvider.getBirthday());
return row;
}
#Override
public void clear()
{
list.clear();
}
}
public class DataProvider {
private String Name;
private String Age;
private String Birthday;
....getter and setters method
After analyzing your code, i found following problems :-
In List adapter you didn't set the tag to row so it always return null layoutHandler and your casting EditText to TextView , i didn't get your point here if you want TextView then use same view in XML.
So the ListAdapter Looks like this.
public class ListAdapter extends ArrayAdapter {
List list = new ArrayList();
static class LayoutHandler
{
EditText NAME,AGE,BIRTHDAY;
}
public ListAdapter(Context context, int resource) {
super(context, resource);
}
#Override
public void add (Object object)
{
super.add(object);
list.add(object);
}
#Override
public int getCount(){
return list.size();
}
#Override
public Object getItem(int position)
{
return list.get(position);
}
#Override
public View getView (int position, View convertView, ViewGroup parent){
View row = convertView;
LayoutHandler layoutHandler;
if (row==null)
{
LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.custom_layout,parent,false);
layoutHandler = new LayoutHandler();
layoutHandler.NAME = (EditText) row.findViewById(R.id.text_user_name);
layoutHandler.AGE = (EditText) row.findViewById(R.id.text_user_age);
layoutHandler.BIRTHDAY = (EditText) row.findViewById(R.id.text_user_birthday);
row.setTag(layoutHandler);
}
else
{
layoutHandler = (LayoutHandler) row.getTag();
}
DataProvider dataProvider = (DataProvider) this.getItem(position);
layoutHandler.NAME.setText(dataProvider.getName());
layoutHandler.AGE.setText(dataProvider.getAge());
layoutHandler.BIRTHDAY .setText(dataProvider.getBirthday());
return row;
}
#Override
public void clear()
{
list.clear();
}
}
and coming to the actual problem i.e. ListView OnItemLongClickListener crashing. You just have to change
final View clicklist = v;
to
final View clicklist = arg0.getChildAt(index);
and then you go. :)
A better way to this is to
1) Create a Custom Class for example Data and add properties that you
want to display within that class.
2) Create an Adapter and populate your adapter with arraylist of Data class.
3) Retrieve the values from listview using onItemClicklistener.
modify your toast
Toast.makeText(DataListActivity.this,"name"+selname+"age"+
selage+"DOB"+ selbirthday,Toast.LENGTH_LONG).show();
All! I'am new in android app. Now I have some problem. I can't see the result of changing list right away (after updating listView in my ListFragment).
For example, i called method addNewItem and I didn't see any changes on the screen. But if I touch ListFragment I will see all my changes.
ListFragment:
public class PointsListFragment extends ListFragment {
PlaceItemsAdapter adapter;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
adapter = new PlaceItemsAdapter(
getActivity(), R.layout.place_list_item,
new ArrayList<PlaceItem>());
setListAdapter(adapter);
adapter.notifyDataSetChanged();
}
public void addNewItem(int id, String address) {
adapter.items.add(new PlaceItem(id, address));
adapter.notifyDataSetChanged();
}
private class PlaceItemsAdapter extends ArrayAdapter<PlaceItem> {
private final int viewResourceId;
final public ArrayList<PlaceItem> items;
#Override
public int getCount() {
return items.size();
}
#Nullable
#Override
public PlaceItem getItem(int position) {
return items.get(position);
}
public PlaceItemsAdapter(Context context, int viewResourceId, ArrayList<PlaceItem> items) {
super(context, viewResourceId, items);
this.items = items;
this.viewResourceId = viewResourceId;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(viewResourceId, null);
}
PlaceItem placeItem = getItem(position);
TextView placeIdTextView = (TextView) v.findViewById(R.id.placeId);
placeIdTextView.setText(String.valueOf(placeItem.getId()));
TextView placeAddressView = (TextView) v.findViewById(R.id.placeAddress);
placeAddressView.setText(placeItem.getAddress());
if (selectedValue == position) {
v.setBackgroundResource(R.drawable.active_item);
}
return v;
}
}
}
My activity xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"[enter image description here][1]
android:padding="2dp">
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:background="#color/forBorder"
android:orientation="horizontal">
<Spinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/spinner"
android:layout_weight="1" />
<TextView
android:text="проложить маршрут"
android:textColor="#android:color/white"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:drawable/ic_media_ff" />
</LinearLayout>
<fragment
class="com.restfulrobot.cdcapplication.PointsListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/list_frag" />
</LinearLayout>
Image Example
Thank you, ALL! I found the answer! I called method from another class (no Activity or Fragment). And now I also call method from another class, but i do it through Handler. And it really works fine now!
Something like that:
Message msg = mainActivityHandler.obtainMessage(MainActivity.NEW_MESSAGE, someObjectToAdd);
mainActivityHandler.sendMessage(msg);
I am using Custom Adapter for ListView. Each ListView item contains ImageButton which will delete that Item. Now, I want to refresh full ListView when anyone click on ImageButton. How to do this ?
Or is there anyway to check ImageButton click on ListView onItemClickListener ? I have already tried notifyDataSetChanged in Custom Adapter but I can't find any changes.
Custom Item xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/lightish"
android:orientation="vertical"
android:padding="10dp" >
<ImageButton
android:id="#+id/imgDelete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginBottom="-20dp"
android:background="#android:color/transparent"
android:contentDescription="#string/app_name"
android:src="#drawable/ic_delete" />
<TextView
android:id="#+id/tvName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:textSize="20sp" />
</LinearLayout>
Custom Adapter java :
public class MyAddressesAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater = null;
View vi;
HashMap<String, String> address;
public MyAddressesAdapter(Activity a,
ArrayList<HashMap<String, String>> arlData) {
activity = a;
data = arlData;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, final View convertView, ViewGroup parent) {
vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.my_address_view, parent, false);
final TextView tvName = (TextView) vi.findViewById(R.id.tvName);
address = new HashMap<String, String>();
address = data.get(position);
tvName.setText(address.get("PersonName"));
return vi;
}
In main activity java :
myAddressesAdapter = new MyAddressesAdapter(
getActivity(), addressList);
lvMyAddresses.setAdapter(myAddressesAdapter);
put code in getview method in adapter
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//your code here
data.remove(position);
notifyDataSetChanged();
}
});
I have a question, currently I am using CursorTreeAdapter however I want to change it to use any other data not just cursors, but to be honest im not sure how would I do that, I think implement some other adapter and then override needed methods? But could any one show me some way? I'm confused right now and don't know to what direction I should go.
Thanks for help.
Abstract classes you can extend: BaseAdapter ArrayAdapter.
You can see this example:
public class FeedAdapter extends BaseAdapter {
private ArrayList<FeedItem> items;
private LayoutInflater layoutInflater;
FeedAdapter(Context context, ArrayList<FeedItem> list, int bgColor){
items = list;
layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return items.size();
}
#Override
public FeedItem getItem(int index) {
return items.get(index);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row;
if (null == convertView) {
row = layoutInflater.inflate(R.layout.romanblack_feed_item, null);
} else {
row = convertView;
}
TextView title = (TextView) row.findViewById(R.id.romanblack_rss_title);
TextView pubdate = (TextView) row.findViewById(R.id.romanblack_rss_pubdate);
String titleString = items.get(position).getTitle();
title.setText(titleString);
if(items.get(position).getTextColor() != Color.TRANSPARENT){
title.setTextColor(items.get(position).getTextColor());
}else{
title.setTextColor(Color.DKGRAY);
}
pubdate.setText(items.get(position).getPubdate());
return row;
}
}
and layout file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/romanblack_feed_item"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#FFF">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/romanblack_rss_bg_feed"
android:orientation="vertical">
<TextView
android:text="Title"
android:id="#+id/romanblack_rss_title"
android:textSize="14sp"
android:textColor="#222"
android:layout_margin="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:text="2011-01-01"
android:id="#+id/romanblack_rss_pubdate"
android:textSize="10sp"
android:textColor="#666"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
we want to create a list view using adapter and we want to set the properties of the the list item outside the adapter.
For instance ,the list view contains 200 rows and 14 column, then we need to create the list item using adapter.Here the objects in adapter is creating based on the which items shown in screen.
After creating adapter ,after outside adapter we want to put getter,setter for the item 198 means .If initially in device the items upto 10 is diplayed means then then 10 items objects is created in adapter but the remaining is created when user scroll down
So null pointer execption is arised for the item 198.
I want to create a ListView as a custom component.In that the user can add any number of rows,any number of columns,etc
Any items as a list view,etc.
My aim is to create library for list view .In that list view user can add any number of rows,any number of columns,any items textview,spinner,etc.I need suggestions how to achieve it
All are welcome to give their ideas.
try use:
your xml list file item.xml:
<LinearLayout>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<CheckBox
android:id="#+id/cbBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</CheckBox>
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="#+id/tvDescr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text=""
android:textSize="20sp">
</TextView>
<TextView
android:id="#+id/tvPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginRight="10dp"
android:text="">
</TextView>
</LinearLayout>
<ImageView
android:id="#+id/ivImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher">
</ImageView>
<LinearLayout/>
And your class adapter
public class BoxAdapter extends BaseAdapter {
Context ctx;
LayoutInflater lInflater;
ArrayList<Product> objects;
BoxAdapter(Context context, ArrayList<Product> products) {
ctx = context;
objects = products;
lInflater = (LayoutInflater) ctx
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return objects.size();
}
#Override
public Object getItem(int position) {
return objects.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = lInflater.inflate(R.layout.item, parent, false);
}
Product p = getProduct(position);
((TextView) view.findViewById(R.id.tvDescr)).setText(p.name);
((TextView) view.findViewById(R.id.tvPrice)).setText(p.price + "");
((ImageView) view.findViewById(R.id.ivImage)).setImageResource(p.image);
CheckBox cbBuy = (CheckBox) view.findViewById(R.id.cbBox);
cbBuy.setOnCheckedChangeListener(myCheckChangList);
cbBuy.setTag(position);
cbBuy.setChecked(p.box);
return view;
}
Product getProduct(int position) {
return ((Product) getItem(position));
}
ArrayList<Product> getBox() {
ArrayList<Product> box = new ArrayList<Product>();
for (Product p : objects) {
if (p.box)
box.add(p);
}
return box;
}
OnCheckedChangeListener myCheckChangList = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
getProduct((Integer) buttonView.getTag()).box = isChecked;
}
};
}
And your class for product
public class Product {
String name;
int price;
int image;
boolean box;
Product(String _describe, int _price, int _image, boolean _box) {
name = _describe;
price = _price;
image = _image;
box = _box;
}
}
And your main activity use the create adapter
boxAdapter = new BoxAdapter(this, products);
ArrayList<Product> products = new ArrayList<Product>();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
...
//create adapter
fillData()
boxAdapter = new BoxAdapter(this, products);
// use lists
ListView lvMain = (ListView) findViewById(R.id.lvMain);
lvMain.setAdapter(boxAdapter);
}
// data for adapter
void fillData() {
for (int i = 1; i <= 20; i++) {
products.add(new Product("Product " + i, i * 1000, R.drawable.ic_launcher, false));
}
What you need is to implement LazyListView.
And I think you have a nice tutorial here to start with.