I try to set a Customer Adapter to ListView but always receive NullException.
This is my Adapter:
public class MovieAdapter extends BaseAdapter{
private Context mContext;
// Add mVar of resource, an array for example
private List<Movie> mMovies;
// Automatically create constructor for all mVar
public MovieAdapter(Context context, List<Movie> movies) {
mContext = context;
mMovies = movies;
}
public MovieAdapter(Callback<NowPlaying> callback, List<Movie> movies) {
}
// Automatically create required methods and override them with mVar
#Override
public int getCount() {
return mMovies.size();
}
#Override
public Object getItem(int position) {
return mMovies.get(position);
}
#Override
public long getItemId(int position) {
return 0; // Use to easier get position reference
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
// If the ListView is brand new
convertView = LayoutInflater.from(mContext).inflate(R.layout.list_movie_item,
parent, false);
// Get layout from the context and inflate it the daily_list_item.
// Use ViewHolder to create smooth scrolling list
holder = new ViewHolder(convertView);
// Set the tag for reuse the View
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//Set content to holderVar from get
//Create the ModelClass object as an element in the array
// Remember even the Image need to be set (different from MainAct)
Movie movie = mMovies.get(position);
holder.mTvLeftTitle.setText(movie.getTitle());
holder.mTvLeftOverview.setText(movie.getOverview());
// holder.mTvLeftCast.setText(movie.getCast());
Glide.with(mContext)
.load(movie.getPosterPath())
.into(holder.mImgLeftPoster);
holder.mTvRightTitle.setText(movie.getTitle());
holder.mTvRightOverview.setText(movie.getOverview());
// holder.mTvLeftCast.setText(movie.getCast());
Glide.with(mContext)
.load(movie.getPosterPath())
.into(holder.mImgRightPoster);
return convertView;
}
// Create class ViewHolder with Widget as variable based on Model class
static class ViewHolder {
// Using ButterKnife to create and hook Widget (remember the Image, too)
#BindView(R.id.rlLeftLayout)
RelativeLayout mRlLeftLayout;
#BindView(R.id.tvLeftTitle)
TextView mTvLeftTitle;
#BindView(R.id.tvLeftOverview)
TextView mTvLeftOverview;
#BindView(R.id.tvLeftCast)
TextView mTvLeftCast;
#BindView(R.id.imgLeftPoster)
ImageView mImgLeftPoster;
#BindView(R.id.rlRightLayout)
RelativeLayout mRlRightLayout;
#BindView(R.id.tvRightTitle)
TextView mTvRightTitle;
#BindView(R.id.tvRightOverview)
TextView mTvRightOverview;
#BindView(R.id.tvRightCast)
TextView mTvRightCast;
#BindView(R.id.imgRightPoster)
ImageView mImgRightPoster;
ViewHolder(View view) {
ButterKnife.bind(this, view);
}
}
}
This is my Activity:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
MovieAdapter mAdapter;
List<Movie> mMovies = new ArrayList<Movie>();
private NowPlaying mNowPlaying;
#BindView(android.R.id.list)
ListView mListView;
#BindView(android.R.id.empty)
TextView mEmptyView;
private MovieApi mMovieApi;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
// final MovieAdapter adapter = new MovieAdapter(this, mMovies);
//
mMovieApi = RetrofitUtils.get(getString(R.string.api_key)).create(MovieApi.class);
mMovieApi.getNowPlaying().enqueue(new Callback<NowPlaying>() {
#Override
public void onResponse(Call<NowPlaying> call, Response<NowPlaying> response) {
Log.d("Response", String.valueOf(response.isSuccessful()));
mMovies = response.body().getMovies();
mAdapter = new MovieAdapter(this, mMovies);
mListView.setAdapter(mAdapter);
mListView.setEmptyView(mEmptyView);
}
#Override
public void onFailure(Call<NowPlaying> call, Throwable t) {
Log.e("Error", t.getMessage());
Toast.makeText(MainActivity.this, "OK", Toast.LENGTH_SHORT).show();
}
});
}
}
My Stack Trace:
10-15 23:04:19.480 12537-12537/com.example.rubit1359.bigcornbox E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.rubit1359.bigcornbox, PID: 12363
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at com.example.rubit1359.bigcornbox.ui.MainActivity$1.onResponse(MainActivity.java:57)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5637)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
I have debugged the app to make sure that the mMovies ListView are filled. However I cannot set the Adapter. Anyone can help me spotting the error.
Thank you.
UPDATE XML
XML activity
<?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:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/darkness"
tools:context="com.example.rubit1359.bigcornbox.ui.MainActivity">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:id="#+id/ListView"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"/>
<TextView
android:text="There is no data to display"
android:textStyle="bold"
android:textSize="20sp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textColor="#color/colorWhite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/EmptyView"
/>
</RelativeLayout>
Adapter xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/darkness">
<RelativeLayout
android:id="#+id/rlLeftLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:background="#color/skypeGray">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/imgLeftScoreBackground"
android:layout_alignTop="#+id/imgLeftPoster"
android:layout_toEndOf="#+id/imgLeftScoreBackground"
android:layout_toRightOf="#+id/imgLeftScoreBackground"
android:gravity="center_vertical"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="#+id/tvLeftTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingExtra="5dp"
android:text="Captain America: Civil War"
android:textAlignment="viewEnd"
android:textColor="#color/redmilk"
android:textSize="15sp"
android:textStyle="bold"/>
<TextView
android:id="#+id/tvLeftOverview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:ellipsize="end"
android:lineSpacingExtra="5dp"
android:maxLines="5"
android:text="Following the events of Age of Ultron, the collective goverments of the world pass an act designed to regulate all superhuman activity. This polarizes opinion amongst the Avengers, causing two factions to side..."
android:textAlignment="viewEnd"
android:textColor="#color/colorWhite"
android:textSize="12sp"/>
<TextView
android:id="#+id/tvLeftCast"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="Chris Evans, Robert Downey Jr."
android:textAlignment="viewEnd"
android:textColor="#color/colorWhite"
android:textSize="12sp"
android:textStyle="bold|italic"/>
</LinearLayout>
<ImageView
android:id="#+id/imgLeftPoster"
android:layout_width="120dp"
android:layout_height="180dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
app:srcCompat="#drawable/poster"/>
<ImageView
android:id="#+id/imgLeftScoreBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/imgLeftPoster"
android:layout_marginTop="3dp"
app:srcCompat="#drawable/background"/>
</RelativeLayout>
<RelativeLayout
android:id="#+id/rlRightLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="#color/skypeGray">
<ImageView
android:id="#+id/imgRightPoster"
android:layout_width="120dp"
android:layout_height="180dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
app:srcCompat="#drawable/poster"/>
<ImageView
android:id="#+id/imgRightScoreBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/imgRightPoster"
android:layout_marginTop="3dp"
app:srcCompat="#drawable/background_right"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/imgRightScoreBackground"
android:layout_alignTop="#+id/imgRightPoster"
android:layout_toLeftOf="#+id/imgRightScoreBackground"
android:layout_toStartOf="#+id/imgRightScoreBackground"
android:gravity="center_vertical"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="#+id/tvRightTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingExtra="5dp"
android:text="Captain America: Civil War"
android:textAlignment="viewStart"
android:textColor="#color/redmilk"
android:textSize="15sp"
android:textStyle="bold"/>
<TextView
android:id="#+id/tvRightOverview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:ellipsize="end"
android:lineSpacingExtra="5dp"
android:maxLines="5"
android:text="Following the events of Age of Ultron, the collective goverments of the world pass an act designed to regulate all superhuman activity. This polarizes opinion amongst the Avengers, causing two factions to side..."
android:textAlignment="viewStart"
android:textColor="#color/colorWhite"
android:textSize="12sp"/>
<TextView
android:id="#+id/tvRightCast"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="Chris Evans, Robert Downey Jr."
android:textAlignment="viewStart"
android:textColor="#color/colorWhite"
android:textSize="12sp"
android:textStyle="bold|italic"/>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
You are getting a wrong id:
Change these lines:
#BindView(android.R.id.list)
ListView mListView;
to :
#BindView(R.id.ListView)
ListView mListView;
You are using listview id which is inbuild android.R.id.list which requires you to extend your activity with ListActivity.
So extend your activity with ListActivity. like this
public class MainActivity extends ListActivity
Or, If you use use custom listview with your id, then use same activity, just give proper id which you defined in your xml file and initialize it.
Something like this
ListView list = (ListView) view.findViewById(R.id.yourlistviewid);
Related
I have made a custom ArrayAdapter and tried to add the another TextView "Breed" of the animals, but when i execute the program , its not showing the Breed. Where am i doing wrong ? I am scratching my head since long. please help where is the mistake ?
MainActivity.Java
public class MainActivity extends AppCompatActivity {
ListView simpleList;
ArrayList<Item> animalList=new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
simpleList = (ListView) findViewById(R.id.simpleListView);
animalList.add(new Item("Lion",R.drawable.lion,"Khatarnak"));
animalList.add(new Item("Tiger",R.drawable.tiger,"Fudu"));
animalList.add(new Item("Monkey",R.drawable.monkey,"Lallu"));
animalList.add(new Item("Elephant",R.drawable.elephant,"Jabardast"));
animalList.add(new Item("Dog",R.drawable.dog,"ItemDog"));
animalList.add(new Item("Cat",R.drawable.cat,"MeeMee"));
MyAdapter myAdapter=new MyAdapter(this,R.layout.list_view_items,animalList);
simpleList.setAdapter(myAdapter);
}
}
MyAdapter.Java
public class MyAdapter extends ArrayAdapter<Item> {
ArrayList<Item> animalList = new ArrayList<>();
public MyAdapter(Context context, int textViewResourceId, ArrayList<Item> objects) {
super(context, textViewResourceId, objects);
animalList = objects;
}
#Override
public int getCount() {
return super.getCount();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.list_view_items, null);
TextView textView = (TextView) v.findViewById(R.id.textView);
ImageView imageView = (ImageView) v.findViewById(R.id.imageView);
TextView breedView = (TextView)v.findViewById(R.id.breed);
textView.setText(animalList.get(position).getAnimalName());
imageView.setImageResource(animalList.get(position).getAnimalImage());
breedView.setText(animalList.get(position).getBreed());
return v;
}
}
Item.Java
public class Item {
String animalName;
int animalImage;
String breedName;
public String getBreed() {
return breedName;
}
public void setBreed(String breed) {
this.breedName = breedName;
}
public Item(String animalName,int animalImage,String breedName)
{
this.animalImage=animalImage;
this.animalName=animalName;
this.breedName = breedName;
}
public String getAnimalName()
{
return animalName;
}
public int getAnimalImage()
{
return animalImage;
}
}
activity_main.xml
<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="match_parent"
tools:context=".MainActivity">
<ListView
android:id="#+id/simpleListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#000"
android:dividerHeight="2dp"/>
</RelativeLayout>
list_view_items.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="5dp" />
<TextView
android:id="#+id/textView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Demo"
android:textColor="#000" />
<TextView
android:id="#+id/breed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Breed"
android:textColor="#000" />
</LinearLayout>
This is most likely a problem with the linear layout for each item. The orientation is horizontal, which lays each view one after the other horizontally. The problem is that the text view for the animal type has a width of fill_parent leaving no space for the breed view. If you change it to wrap_content it'll probably work for some of the cases, but might not work with everything.
In any case I think this is a problem with the views' positions and sizes. Try and move them around. Perhaps even a simple change would be placing them vertically:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="5dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/textView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Demo"
android:textColor="#000" />
<TextView
android:id="#+id/breed"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Breed"
android:textColor="#000" />
</LinearLayout>
</LinearLayout>
There's perhaps a more efficient way of doing this, but this is just an example. The inner linear layout places one text view on to of the other.
PS: your getCount method is not really doing anything. You can remove it.
replace your layout with my code your issue will resolve.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="5dp" />
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:text="Demo"
android:textColor="#000" />
<TextView
android:id="#+id/breed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Breed"
android:textColor="#000" />
</LinearLayout>
I am trying to create an activity where the user can create some recipe and input the ingredients. every time the user enters an ingredient, it should be added to a listview. The issue I am having here is that the first input is the only one that is added to the listview not the others.
Here is the layout script:
<?xml version="1.0" encoding="utf-8"?><ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Activities.AddActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="226dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:orientation="vertical">
<EditText
android:id="#+id/Name_ET"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="#string/recipe_name" />
<EditText
android:id="#+id/ServingsNbr_ET"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="#string/number_of_servings" />
<EditText
android:id="#+id/PrepTime_Et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="#string/preparation_time" />
<EditText
android:id="#+id/Calories_ET"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="#string/calories" />
</LinearLayout>
<LinearLayout
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="36dp"
android:text="#string/ingredients"
android:textSize="26sp"
android:textAlignment="center"
android:textStyle="bold"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="#+id/new_ing"
android:layout_width="0dp"
android:layout_weight="9"
android:layout_height="36dp" />
<ImageView
android:id="#+id/add_ingredient_btn"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="36dp"
android:src="#drawable/round_add_circle_outline_black_36dp"/>
</LinearLayout>
<ListView
android:id="#+id/ingredient_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView>
</LinearLayout>
</LinearLayout>
And the logic behind it :
public class AddActivity extends AppCompatActivity {
private ListView added_ing;
private IngredientAdapter adapter;
private ArrayList<String> ingredients = new ArrayList<String>();
private EditText new_ing;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
adapter = new IngredientAdapter(AddActivity.this,ingredients);
added_ing = findViewById(R.id.ingredient_list);
added_ing.setAdapter(adapter);
new_ing = findViewById(R.id.new_ing);
ImageView add_ingredien = findViewById(R.id.add_ingredient_btn);
add_ingredien.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ingredients.add(new_ing.getText().toString());
Toast.makeText(AddActivity.this, new_ing.getText().toString(), Toast.LENGTH_SHORT).show();
adapter.notifyDataSetChanged();
}
});
}
public class IngredientAdapter extends ArrayAdapter<String> {
ArrayList<String> mNewIngredients;
public IngredientAdapter(Context context, ArrayList<String> objects) {
super(context, 0, objects);
mNewIngredients = objects;
}
public String getItem(int position) {
return mNewIngredients.get(position).toString();
}
public View getView(int position, View convertView, ViewGroup parent) {
String item = getItem(position);
if(convertView==null)
convertView = LayoutInflater.from(getContext()).inflate(R.layout.ingredient,parent,false);
TextView recipeName= convertView.findViewById(R.id.new_added_ingredient);
recipeName.setText(item);
return convertView;
}
}
}
Try to scroll down your list view, maybe in your item's layout, you set the layout_height = match_parent so you do not see the other inputs.
You need to add android:fillViewport="true" to your ScrollView
Also change all child LinearLayout height to wrap_content instead of match_parent
Try this
<?xml version="1.0" encoding="utf-8"?><ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:fillViewport="true"
android:layout_height="match_parent"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="226dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:orientation="vertical">
<EditText
android:id="#+id/Name_ET"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="#string/app_name" />
<EditText
android:id="#+id/ServingsNbr_ET"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="#string/app_name" />
<EditText
android:id="#+id/PrepTime_Et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="#string/app_name" />
<EditText
android:id="#+id/Calories_ET"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="#string/app_name" />
</LinearLayout>
<LinearLayout
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="36dp"
android:text="#string/app_name"
android:textSize="26sp"
android:textAlignment="center"
android:textStyle="bold"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="#+id/new_ing"
android:layout_width="0dp"
android:layout_weight="9"
android:layout_height="36dp" />
<ImageView
android:id="#+id/add_ingredient_btn"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="36dp"
android:src="#drawable/ic_launcher_background"/>
</LinearLayout>
<ListView
android:id="#+id/ingredient_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView>
</LinearLayout>
</LinearLayout>
</ScrollView>
In your implementation of IngredientAdapter, you are using your own ArrayList mNewIngredients for the data instead of the collection in the ArrayAdapter. When you add new data into ingredients, it is not added to the adapter.
To make use of the collection implemented in ArrayAdapter for simplicity. The following is an example, with a view holder so that views can be reused.
public class IngredientAdapter extends ArrayAdapter<String> {
public IngredientAdapter(Context context, ArrayList<String> objects) {
super(context, 0, objects);
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView==null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.ingredient, parent, false);
holder = new ViewHolder();
holder.recipeName = convertView.findViewById(R.id.new_added_ingredient);
convertView.Tag = holder;
} else {
holder = (ViewHolder)convertView.Tag;
}
String item = getItem(position);
holder.recipeName.setText(item);
return convertView;
}
}
public class ViewHolder {
public TextView recipeName;
}
The data in the adapter is now backed by the internal collection. And in the activity, you should add the new data into adapter directly.
public class AddActivity extends AppCompatActivity {
private ListView added_ing;
private IngredientAdapter adapter;
// keep this if you need it for something else
// private ArrayList<String> ingredients = new ArrayList<String>();
private EditText new_ing;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
adapter = new IngredientAdapter(AddActivity.this,ingredients);
added_ing = findViewById(R.id.ingredient_list);
added_ing.setAdapter(adapter);
new_ing = findViewById(R.id.new_ing);
ImageView add_ingredien = findViewById(R.id.add_ingredient_btn);
add_ingredien.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// keep this if you need it for something else
// ingredients.add(new_ing.getText().toString());
// to add adata into the adapter
adapter.Add(new_ing.getText().toString());
Toast.makeText(AddActivity.this, new_ing.getText().toString(), Toast.LENGTH_SHORT).show();
adapter.notifyDataSetChanged();
}
});
}
}
i have a problem with my ListView , I cannot get the data from an arraylist to listview . Data from arraylist was loaded successful from the data and when I put it in the ArrayAdapter the app always say ArrayAdapter requires the resource ID to be a TextView
Here my code
EventList.java
public class EventList extends Activity {
ListView listView;
DBHelper db;
List<String> event_name;
private TextView e_name,e_location,e_date,e_time,e_or;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event_list);
db = new DBHelper(this);
listView = (ListView) findViewById(R.id.eventlist);
db.open();
ArrayList<Event> elist= db.getEventlist();
db.close();
e_name=(TextView) findViewById(R.id.e_name);
e_date=(TextView) findViewById(R.id.e_date);
e_location =(TextView) findViewById(R.id.e_location);
e_time =(TextView) findViewById(R.id.e_time);
e_or =(TextView) findViewById(R.id.e_or);
// for(int i=0;i<elist.size();i++)
// {
// e_name.setText(elist.get(i).getEventName());
// e_date.setText(elist.get(i).getDate());
// e_location.setText(elist.get(i).getLocation());
// e_time.setText(elist.get(i).getTime());
// e_or.setText(elist.get(i).getOrganizer());
// }
ArrayAdapter<Event> arrayAdapter = new ArrayAdapter<Event>(
this,
R.layout.each_event,elist);
listView.setAdapter(arrayAdapter);
}
}
activity_event_list.xml
<?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="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.greenwich.thaotb.eventmanagement.EventList">
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Event List"
android:id="#+id/textView2"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Event"
android:id="#+id/textView3"
android:layout_marginTop="26dp"
android:layout_below="#+id/textView2"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:text="Event"
android:ems="10"
android:id="#+id/event_name"
android:layout_alignBottom="#+id/textView3"
android:layout_toRightOf="#+id/textView3"
android:layout_toEndOf="#+id/textView3"
android:layout_marginLeft="33dp"
android:layout_marginStart="33dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Search"
android:id="#+id/bnt_search"
android:layout_below="#+id/event_name"
android:layout_alignRight="#+id/event_name"
android:layout_alignEnd="#+id/event_name" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/eventlist"
android:layout_below="#+id/bnt_search"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:choiceMode="singleChoice" />
</RelativeLayout>
each_event.xml
<?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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/e_name" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/e_location" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/e_date" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/e_time" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/e_or" />
</LinearLayout>
Take a look at the documentation for the the constructor for ArrayAdapter that you're using. It says the resource ID must be a layout with a TextView. It turns out, in this case, that the layout must contain ONLY a single TextView. If you have a different case, use a different constructor.
ArrayAdapter populates a ListView by taking the toString() value of the object in its array, then putting that into the TextView identified by the layout you passed.
Two problems
You can't use the ArrayAdapter constructor for displaying any complex data objects. It will just toString all the objects.
Calling findViewById(R.id.e_name) (and the others) from within the Activity will return null because #+id/e_name isn't from the activity_event_list.xml file.
To solve these, you'll need to implement a custom ArrayAdapter for your Event objects.
Something like so
public class EventAdapter extends ArrayAdapter<Event> {
public EventAdapter(Context context, ArrayList<Event> events) {
super(context, 0, events);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Event event = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.each_event, parent, false);
}
TextView eName = (TextView) convertView.findViewById(R.id.e_name);
// get other views ...
eName.setText(event.getEventName());
// set other views...
return convertView;
}
}
Then in the Activity, you can do
ArrayList<Event> elist= db.getEventlist();
EventAdapter adapter = new EventAdapter(this, elist);
listView.setAdapter(adapter);
I have read your code, and I think it's worth first checking how ListViews and and Adapters work together. Here's a great article I think you should take a look at.
Solution
You can achieve what you want by
Creating a custom class that represents an event, it should be something like this
class Event{
private String mName;
private String mLocation;
private String mDate;
//you get the idea ...
public Event (String name, String location, String date){
mName = name;
mLocation = location;
mDate = date;
}
//some getters
public String getName (){
return mName;
}
public String getLocation (){
return mLocation;
}
public String getDate (){
return mDate;
}
//you can add other logic here depending on what you want your event to do
}
Creating you collection of Events, a List<Event> will do
Creating your custom EventAdapter, I would recommend to extend the BaseAdapter class (any other Adapter class would do)
A tutorial might help you more
Here is a great step by step tutorial showing how to implement what I have mentioned above.
I have a list that when you click on the row on the right side the layout with the icon is changed by other. This makes it well but when I scrolling in the list, I notice there are rows with the same icon without do click. Also, if I scroll quickly these same icons are lost and are built differently. I think it's on the reuse of cells but I can not find the solution. What I want is that the image stays active only in the row where clicka.
Thanks!!
Adapter class:
public class ListadoVotantesArrayAdapter extends ArrayAdapter<Votante> {
private Context context;
private LayoutInflater inflater;
private ArrayList<Votante> listaVotantes;
private int rowLayout;
private View mConverView;
public ListadoVotantesArrayAdapter(Context context, int resource, ArrayList<Votante> objects) {
super(context, resource,objects);
this.context = context;
this.inflater = LayoutInflater.from(context);
this.listaVotantes = objects;
this.rowLayout = resource;
}
public int getCount(){
return this.listaVotantes.size();
}
public Votante getVotante(int position){
return this.listaVotantes.get(position);
}
private static class ViewHolder {
public TextView lblName;
public TextView lblLastName;
public TextView lblDni;
public TextView lblVoterNumber;
public RelativeLayout lytVoted;
public RelativeLayout lytCanVote;
public RelativeLayout lytUndo;
}
public View getView(int position, View converView, ViewGroup parent) {
final ViewHolder viewHolder;
mConverView = converView;
if (mConverView == null){
viewHolder = new ViewHolder();
this.mConverView = inflater.inflate(this.rowLayout, parent, false);
if (mConverView != null){
viewHolder.lblName = (TextView) mConverView.findViewById(R.id.lblVoterName);
viewHolder.lblLastName = (TextView) mConverView.findViewById(R.id.lblVoterLastName);
viewHolder.lblDni = (TextView) mConverView.findViewById(R.id.lblDni);
viewHolder.lblVoterNumber = (TextView) mConverView.findViewById(R.id.lblNumber);
viewHolder.lytVoted = (RelativeLayout) mConverView.findViewById(R.id.lytVoted);
viewHolder.lytCanVote = (RelativeLayout) mConverView.findViewById(R.id.lytCanVote);
viewHolder.lytUndo = (RelativeLayout) mConverView.findViewById(R.id.lytUndo);
mConverView.setTag(viewHolder);
}
}else{
viewHolder = (ViewHolder) mConverView.getTag();
}
Votante votante = getVotante(position);
viewHolder.lblName.setText(votante.getNombre());
viewHolder.lblLastName.setText(votante.getApellidos());
viewHolder.lblDni.setText(votante.getDni());
viewHolder.lblVoterNumber.setText(""+votante.getNumVotante());
if (votante.getVotado()){
viewHolder.lytVoted.setVisibility(View.VISIBLE);
viewHolder.lytCanVote.setVisibility(View.GONE);
}else{
viewHolder.lytVoted.setVisibility(View.GONE);
viewHolder.lytCanVote.setVisibility(View.VISIBLE);
}
mConverView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewHolder.lytUndo.setVisibility(View.VISIBLE);
notifyDataSetChanged();
}
});
return mConverView;
}
}
Layout Row:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lyt_voter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="1dp">
<RelativeLayout
android:id="#+id/lytVoterNumber"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentLeft="true"
android:background="#color/lightBlueItemList">
<TextView
android:id="#+id/lblNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="1999"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
<LinearLayout
android:id="#+id/lytVoterData"
android:layout_width="wrap_content"
android:layout_height="70dp"
android:layout_alignParentTop="true"
android:layout_toLeftOf="#+id/lytCanVote"
android:layout_toRightOf="#+id/lytVoterNumber"
android:layout_toStartOf="#+id/lytCanVote"
android:background="#color/whiteItemList"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:id="#+id/lblVoterLastName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Suarez Garcia de la Serna"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/lblVoterName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="José Carlos"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/lblDni"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="44950962S"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
<RelativeLayout
android:id="#+id/lytCanVote"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentRight="true"
android:background="#color/yellowItemList"
android:minHeight="30dp"
android:minWidth="30dp">
<ImageView
android:id="#+id/imgVote"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/flecha" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/lytVoted"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentRight="true"
android:background="#color/grrenAcceptList"
android:minHeight="30dp"
android:minWidth="30dp"
android:visibility="gone">
<ImageView
android:id="#+id/imgAccept"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/aceptar"
/>
</RelativeLayout>
<RelativeLayout
android:layout_width="70dp"
android:layout_height="70dp"
android:minHeight="30dp"
android:minWidth="30dp"
android:background="#color/redD3"
android:id="#+id/lytUndo"
android:layout_alignParentRight="true"
android:visibility="gone">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imgUndo"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:src="#drawable/undo"/>
</RelativeLayout>
</RelativeLayout>
You need to follow below Idea
1) this line of code mConverView = converView; doesn't makes sense. directly use converView(View from getView param). Remove mConvertView from the adapter.
2) Add some mechanism which can tell you which row is clicked and save that variable.
Example:- Have an boolean Array of size Rows.size . and set them in onClick.
Boolean[] array = new Boolean[getSize()];
in onClick that you already have in your getview set this.
public void onClick(View v) {
array[position] = !array[position];
viewHolder.lytUndo.setVisibility(View.VISIBLE);
//You do not need to call notifyDatasetChange.
3) in getView(), when you are setting data in to row items/or just before onClick. have a check like below.
if(array[position])// this will tell you if you need to show or hid lytUndo thing
viewHolder.lytUndo.setVisibility(View.VISIBLE); // Show it
else
viewHolder.lytUndo.setVisibility(View.GONE); // hide it or do whatever you want
You might need to set some params as final
I have written this as simple as possible, comment back with your result.
I am writing an app that requires the user to enter some details into a form. The form initially has 3 EditText views in a row. When the user enters some data in the last editText, the onFocusChangeListener should initiate a new row.
This is what I want to do.
How can I create 3 editText views in a single listView row at runtime?
To create a listView with multiple views in a row, you need to customize your adapter, so it can take the form of your row from a source XML -that you should create- and puts it into your listView, here is an example based on BaseAdapter:
This is your Xml source that contains the form of your Row:
espaceclientuploadsource.xml :
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:addStatesFromChildren="true" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:addStatesFromChildren="true" >
<ImageView
android:id="#+id/Uplodimage"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="15dp"
android:src="#drawable/bingo" />
<TextView
android:id="#+id/UploadedProductName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="24dp"
android:layout_toRightOf="#+id/Uplodimage"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/UplodedProductPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/UploadedProductName"
android:layout_below="#+id/UploadedProductName"
android:layout_marginTop="16dp"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />
<ImageView
android:id="#+id/UploadedStatus"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_above="#+id/UplodedProductPrice"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/UploadedProductName"
android:layout_marginRight="27dp"
android:src="#drawable/bingo" />
<ImageView
android:id="#+id/ImageViewDelete"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_alignBottom="#+id/UplodedProductPrice"
android:layout_alignLeft="#+id/UploadedStatus"
android:clickable="true"
android:src="#drawable/bingo" />
</RelativeLayout>
Then you need to create an XML file that containes your ListView:
espaceclientuploads:
<EditText
android:id="#+id/login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10" >
<requestFocus />
</EditText>
<EditText
android:id="#+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPassword" />
<Button
android:id="#+id/submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="submit"
android:text="Button" />
</LinearLayout>
Next is your adapter, it's role is to use your sourceXML as your row Format,
UploadedAdapter :
public class UploadedAdapter extends BaseAdapter
{
List<Article> lesArticles;
DataSource produitSource;
LayoutInflater inflater;
String path= Environment.getExternalStorageDirectory().toString()+File.separator+"Bingo";
public UploadedAdapter(Context context, List<Article> lesArticles)
{
inflater=LayoutInflater.from(context);
this.lesArticles = lesArticles;
}
#Override
public int getCount()
{
return lesArticles.size();
}
#Override
public Object getItem(int position)
{
return lesArticles.get(position);
}
#Override
public long getItemId(int position)
{
return position;
}
private class ViewHolder
{
TextView nomduProduit;
TextView prixDuProduit;
ImageView status;
ImageView imageDuProduit;
ImageView delete;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView==null)
{
holder=new ViewHolder();
convertView = inflater.inflate(R.layout.espaceclientuploadsource, null);
holder.nomduProduit = (TextView)convertView.findViewById(R.id.UploadedProductName);
holder.prixDuProduit = (TextView)convertView.findViewById(R.id.UplodedProductPrice);
holder.imageDuProduit = (ImageView)convertView.findViewById(R.id.Uplodimage);
holder.status = (ImageView)convertView.findViewById(R.id.UploadedStatus);
holder.delete=(ImageView)convertView.findViewById(R.id.ImageViewDelete);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
Drawable drawableImage = new BitmapDrawable(bitmapImage);
holder.imageDuProduit.setImageDrawable(drawableImage);
holder.nomduProduit.setText(lesArticles.get(position).getNomArticle());
holder.prixDuProduit.setText(lesArticles.get(position).getPrix());
holder.delete.setImageResource(R.drawable.delete);
return convertView;
}
}
As you can see, your adapter extends the baseAdapter which is an abstract class, so you need to Override its method.
Finally it's your activity that will display your listView:
public class EspaceClientUplodedProducts extends Activity{
List<Article> lesArticle= new ArrayList<Article>();
ListView lvListe;
UploadedAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.espaceclientuploads);
lvListe= (ListView)findViewById(R.id.UploadListView);
adapter = new UploadedAdapter(this, lesArticle);
lvListe.setAdapter(adapter);
lvListe.setOnItemClickListener(this);
}
}