I'm new to Android and have been learning about Android app development for about a month just through a book, and right now, I'm working on my own project, which is a basic app that manages user tasks and schedule. There is this one problem I am having. I am trying to add a new task to a RecyclerView list that contains the list of main tasks, but I keep getting errors. Here is what I have (I don't want to show everything because it is a project):
The RecyclerView list (main_task_window.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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/MainTaskList"
android:layout_width="match_parent"
android:layout_height="449dp"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="0dp"
android:layout_marginTop="1dp"
android:layout_marginBottom="61dp" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/AddaMainTask"
android:onClick="addnewtask"
android:layout_width="54dp"
android:layout_height="51dp"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginEnd="13dp"
android:layout_marginBottom="10dp"
android:clickable="true"
app:srcCompat="#android:drawable/ic_input_add" />
</RelativeLayout>
The window that allows users to add new main tasks as well as additional notes (add_new_main_task_window.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">
<EditText
android:id="#+id/maintasks"
android:layout_width="match_parent"
android:layout_height="62dp"
android:hint="Main Task"/>
<EditText
android:id="#+id/notes"
android:layout_width="match_parent"
android:layout_height="62dp"
android:hint="Additional notes"/>
<Button
android:id="#+id/addButton"
android:onClick="sendButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add to main task" />
</LinearLayout>
Now here are the following Java files:
1. MainTasks.java (contains the get and set methods for the main task and additional notes)
package com.ricstudios.daymanager;
public class MainTasks
{
private String mt, an; //'mt' stands for "main tasks". 'an' stands for "additional notes"
//MainTasks class constructor
public MainTasks(String mt, String an)
{
//mt and an in the parameters is equal to the mt and an variables above
this.mt = mt;
this.an = an;
}
public String getMainTasks() //this get method obtains the main task string input)
{
return mt;
}
public void setMainTasks(String MainTasks) //this set methods stores the main task string input)
{
this.mt = MainTasks;
}
public String getAdditionalNotes() //this get method obtains the main task string input
{
return an;
}
public void setAdditionalNotes(String AddNotes) //this set method stores the main task string
{
this.an = AddNotes;
}
}
MainTaskAdapter.java (contains the adapter to render the data)
package com.ricstudios.daymanager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import java.util.List;
public class MainTaskAdapter extends RecyclerView.Adapter<MainTaskAdapter.ViewHolder>
{
private List<MainTasks> maintasklist; //will contain the main task and additional notes string inputs
public class ViewHolder extends RecyclerView.ViewHolder
{
public EditText maintask, addnotes;
//provides a reference to the views for each data item
public ViewHolder(View view)
{
super(view);
maintask = (EditText)view.findViewById(R.id.maintasks);
addnotes = (EditText)view.findViewById(R.id.notes);
}
}
//MainTaskAdapter class constructor
public MainTaskAdapter(List<MainTasks> maintasklist)
{
this.maintasklist = maintasklist;
}
//create new view (invoked by the layout manager)
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.add_new_main_task_window, parent, false);
return new ViewHolder(itemView);
}
//replaces the contents of the main task view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder holder, int position)
{
MainTasks obj = maintasklist.get(position); //MainTasks class obj called 'obj', which allows access to the MainTasks class
//obtains the main task and additional notes from the MainTask class
holder.maintask.setText(obj.getMainTasks());
holder.addnotes.setText(obj.getAdditionalNotes());
}
//returns the size of the main task list (invoked by the layout manager)
#Override
public int getItemCount()
{
return maintasklist.size();
}
}
AddNewMainTask.java (adds the tasks and additional notes to the RecyclerView)
package com.ricstudios.daymanager;
import android.support.v7.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.Button;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
/*This class handles the window for adding new main tasks to the main task list (this window is the add_new_main_task_window.xml layout)*/
public class AddNewMainTask extends AppCompatActivity
{
private Button addbutton; //Button element from the add_new_main_task_window.xml layout
private EditText maintask, addnotes; //EditText elements from the add_new_main_task_window.xml layout
private List<MainTasks> maintasklist = new ArrayList<>();
private RecyclerView ListofMainTasks; //RecyclerView list element from the add_new_main_task_window.xml layout (containing the Main Task list)
private MainTaskAdapter TAdapter; //MainTaskAdapter class object 'TAdapter', allows access to the MainTaskAdapter class
/*sendButton method from the Button element in the add_new_main_task_window.xml and adds the main task and additional notes to the RecyclerView main task list*/
public void sendButton(View view)
{
maintask = (EditText)view.findViewById(R.id.maintasks);
addnotes = (EditText)view.findViewById(R.id.notes);
ListofMainTasks = (RecyclerView)findViewById(R.id.MainTaskList);
TAdapter = new MainTaskAdapter(maintasklist);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
ListofMainTasks.setLayoutManager(mLayoutManager);
ListofMainTasks.setItemAnimator(new DefaultItemAnimator());
ListofMainTasks.setAdapter(TAdapter);
/*Passes the EditText element values into the MainTask.java parameters*/
MainTasks mnt = new MainTasks(maintask.getText().toString(), addnotes.getText().toString());
maintasklist.add(mnt);
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.add_new_main_task_window); //displays the window that allows users to add new main tasks (which is the add_new_main_task_window.xml layout)
addbutton = (Button)findViewById(R.id.addButton);
/*When user clicks button, the values the user puts in the EditText fields will be added to the RecyclerView list of the main_task_window.xml layout*/
addbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
sendButton(v);
}
});
}
}
Whenever I press the "Add to Main Task" button, the app suddenly stop. Please help. Oh, and about the floatingactionbutton in the main_task_window.xml, don't worry about that. That just sends the user to the add_new_main_task_window.xml
Update: 3/5/19
I'm getting this error from the logcat:
03-05 15:22:49.298 10335-10335/com.project.daymanager E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.project.daymanager, PID: 10335
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference
at com.project.daymanager.AddNewMainTask.sendButton(AddNewMainTask.java:39)
at com.project.daymanager.AddNewMainTask$1.onClick(AddNewMainTask.java:63)
at android.view.View.performClick(View.java:5702)
at android.widget.TextView.performClick(TextView.java:10887)
at android.view.View$PerformClick.run(View.java:22541)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Replace
view.findViewById();
with
findViewById();
In the MainTasks.java Don't use a constructor
public MainTasks(String mt, String an)
Just keep the set And get methods and do
MainTasks mt = new MainTasks();
mt.setMainTasks("Title");
mt.setAdditionalNotes("Note");
list.add(mt);
If it still not working, please post the error log so we can know whats the error.
Update: 3/5/19
You are trying to access the recyclerView of the MainTaskActivity in
ListofMainTasks = (RecyclerView)findViewById(R.id.MainTaskList);
from out side the activity (From another Activity) and that's not possible this way,
you can set the RecyclerView in the MainTaskActivity to static and use it in AddNewMainTask Activity by calling it
MainTaskActivity.myRecyclerView.
Problem is in this line:
ListofMainTasks = (RecyclerView)findViewById(R.id.MainTaskList);
program is unable to find recycler view and its null. and you can't set layout manager to a null object. I've reviewed your code and thing you did wrong is that in you onCreate method you are setting layout setContentView(R.layout.add_new_main_task_window); and you're trying to find recylerview which is not in this layout.
Your recycler view is in main_task_window.xml. use setContentView(R.layout.main_task_window.xml); and your activity will find recyclerview easily.
Note: if you want button/controls also which are in this layout add_new_main_task_window.xml then please move them in layout with recyclerview.
What I am trying to do here is to display a list of strings using ArrayList<String> and ArrayAdapter<String> when a user clicks a button. I want to declare all the members i.e. adapter, ArrayList and the list layout as global because I want to add more buttons later with the same feature of displaying a list of strings.
This code has no error but it's not working. I put the Toast in the onClick to make sure the onClick is working. I can see the toast but not the listView I want to see.
class file
R.id.button_news is the button id. R.layout.activity_primary_content is the layout that I'm using in this class PrimaryContent
R.layout.list_view_secondary is the layout where the listView R.id.list_view is located.
R.layout.list_view_secondary layout and the PrimaryContent class are not related but I want to use the listView which is in the list_view_secondary layout to display from the PrimaryContent.
In this line of code
arrayAdapter = new ArrayAdapter<>(view.getContext(),android.R.layout.simple_list_item_1,list); I tried by put the context view.getContext() and getBaseContext() both of them are not working.
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
public class PrimaryContent extends AppCompatActivity {
private final String LOG_TAG = PrimaryContent.class.getSimpleName();
public ListView listView;
public ArrayList<String> arrayList;
public ArrayAdapter<String> arrayAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_primary_content);
final LayoutInflater factory = getLayoutInflater();
final View rootView = factory.inflate(R.layout.list_view_secondary, null);
listView = rootView.findViewById(R.id.list_view);
arrayList = new ArrayList<>();
for (int i=0; i<20; i++) {
arrayList.add("World News");
}
Button news = findViewById(R.id.button_news);
news.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getBaseContext(),"Damn",Toast.LENGTH_SHORT).show();
for (String x: arrayList) {
Log.v(LOG_TAG,x);
System.out.println();
}
arrayAdapter = new ArrayAdapter<>(view.getContext(),android.R.layout.simple_list_item_1,arrayList);
listView.setAdapter(arrayAdapter);
}
});
}
}
R.layout.list_view_secondary
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="true"
android:orientation="vertical" />
You forgot to add the inflated layout to your parent layout, for example:
LinearLayout parentLayout = (LinearLayout) findViewById(R.id.parent_layout);
parentLayout.addView(rootView);
I'm developing an Android app that has to simulate a sort of Pokédex.
For now, what I want to do is simply have all 151 Pokémon printed on my device, so I can scroll them up and down.
The problem is that when I try this thing with such as 9 or 12 images there are no problems, but when I load all the 151 images (all .png), Android kills the app because it's draining too much system resources.
I've heard that there are Java methods that can (don't know how) "destroy" an object when it goes out of the display and then recreate it when it returns in the screen. Anyway if you have different suggestions on how to resolve my problem, every idea is welcome!
Here is my MainActivity:
package com.example.thefe.newsmartkedex;
import android.media.AudioManager;
import android.media.SoundPool;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Toast.makeText(MainActivity.this, "" + position,
Toast.LENGTH_SHORT).show();
}
});
};
}
And here is my ImageAdapter class I use for Gridview:
package com.example.thefe.newsmartkedex;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(200, 200));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
// references to our images
private Integer[] mThumbIds = {
R.drawable.pkmn1, R.drawable.pkmn2,
R.drawable.pkmn3, R.drawable.pkmn4,
R.drawable.pkmn5, R.drawable.pkmn6,
R.drawable.pkmn7, R.drawable.pkmn8,
R.drawable.pkmn9, R.drawable.pkmn10,
R.drawable.pkmn11, R.drawable.pkmn12,
R.drawable.pkmn13, R.drawable.pkmn14,
R.drawable.pkmn15, R.drawable.pkmn16,
R.drawable.pkmn17, R.drawable.pkmn18,
R.drawable.pkmn19, R.drawable.pkmn20,
R.drawable.pkmn21, R.drawable.pkmn22,
R.drawable.pkmn23, R.drawable.pkmn24,
R.drawable.pkmn25, R.drawable.pkmn26,
R.drawable.pkmn27, R.drawable.pkmn28,
R.drawable.pkmn29, R.drawable.pkmn30,
R.drawable.pkmn31, R.drawable.pkmn32,
R.drawable.pkmn33, R.drawable.pkmn34,
R.drawable.pkmn35, R.drawable.pkmn36,
R.drawable.pkmn37, R.drawable.pkmn38,
R.drawable.pkmn39, R.drawable.pkmn40,
R.drawable.pkmn41, R.drawable.pkmn42,
R.drawable.pkmn43, R.drawable.pkmn44,
R.drawable.pkmn45, R.drawable.pkmn46,
R.drawable.pkmn47, R.drawable.pkmn48,
R.drawable.pkmn49, R.drawable.pkmn50,
R.drawable.pkmn51, R.drawable.pkmn52,
R.drawable.pkmn53, R.drawable.pkmn54,
R.drawable.pkmn55, R.drawable.pkmn56,
R.drawable.pkmn57, R.drawable.pkmn58,
R.drawable.pkmn59, R.drawable.pkmn60,
R.drawable.pkmn61, R.drawable.pkmn62,
R.drawable.pkmn63, R.drawable.pkmn64,
R.drawable.pkmn65, R.drawable.pkmn66,
R.drawable.pkmn67, R.drawable.pkmn68,
R.drawable.pkmn69, R.drawable.pkmn70,
R.drawable.pkmn71, R.drawable.pkmn72,
R.drawable.pkmn73, R.drawable.pkmn74,
R.drawable.pkmn75, R.drawable.pkmn76,
R.drawable.pkmn77, R.drawable.pkmn78,
R.drawable.pkmn79, R.drawable.pkmn80,
R.drawable.pkmn81, R.drawable.pkmn82,
R.drawable.pkmn83, R.drawable.pkmn84,
R.drawable.pkmn85, R.drawable.pkmn86,
R.drawable.pkmn87, R.drawable.pkmn88,
R.drawable.pkmn89, R.drawable.pkmn90,
R.drawable.pkmn91, R.drawable.pkmn92,
R.drawable.pkmn93, R.drawable.pkmn94,
R.drawable.pkmn95, R.drawable.pkmn96,
R.drawable.pkmn97, R.drawable.pkmn98,
R.drawable.pkmn99, R.drawable.pkmn100,
R.drawable.pkmn101, R.drawable.pkmn102,
R.drawable.pkmn103, R.drawable.pkmn104,
R.drawable.pkmn105, R.drawable.pkmn106,
R.drawable.pkmn107, R.drawable.pkmn108,
R.drawable.pkmn109, R.drawable.pkmn110,
R.drawable.pkmn111, R.drawable.pkmn112,
R.drawable.pkmn113, R.drawable.pkmn114,
R.drawable.pkmn115, R.drawable.pkmn116,
R.drawable.pkmn117, R.drawable.pkmn118,
R.drawable.pkmn119, R.drawable.pkmn120,
R.drawable.pkmn121, R.drawable.pkmn122,
R.drawable.pkmn123, R.drawable.pkmn124,
R.drawable.pkmn125, R.drawable.pkmn126,
R.drawable.pkmn127, R.drawable.pkmn128,
R.drawable.pkmn129, R.drawable.pkmn130,
R.drawable.pkmn131, R.drawable.pkmn132,
R.drawable.pkmn133, R.drawable.pkmn134,
R.drawable.pkmn135, R.drawable.pkmn136,
R.drawable.pkmn137, R.drawable.pkmn138,
R.drawable.pkmn139, R.drawable.pkmn140,
R.drawable.pkmn141, R.drawable.pkmn142,
R.drawable.pkmn143, R.drawable.pkmn144,
R.drawable.pkmn145, R.drawable.pkmn146,
R.drawable.pkmn147, R.drawable.pkmn148,
R.drawable.pkmn149, R.drawable.pkmn150,
R.drawable.pkmn151
};
}
Finally, this is the XML file
<?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: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.example.thefe.newsmartkedex.MainActivity">
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="90dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>
</RelativeLayout>
Thanks for help!
First of all, I don't see any violation in your code so let's focus the pictures.
The problem is that when I try this thing with such as 9 or 12 images there are no problems, but when I load all the 151 images (all .png), Android kills the app because it's draining too much system resources.
What do you mean by 'load all the 151 images'? At the same time in the same screen? Or you just make quite a small numbers of them(like 9,12,16 etc.) seen in the view and others out of the screen?
I've heard that there are Java methods that can (don't know how) "destroy" an object when it goes out of the display and then recreate it when it returns in the screen. Anyway if you have different suggestions on how to resolve my problem, every idea is welcome!
You can't simply destroy an object by yourself and the Jvm will handle this for you when your objects are invalid or unused. As to this problem the recreation of objects that you implements in 'getView' seems no harm.
My question is: how many images did you show in one whole screen? And what size of them?
If you can provide your demo here, it will be the best to work on.
Display limited images that can fit your screen and load the other images when scrolling Gridview.
That way system wont have do to do lots of work at once. Your application gets faster also.
You can refer this link:
i want grid view with loading by scroll i have image fetch from sever but i want only 10 images view other can load when scrolling grid view
I am making a file explorer in android. So in the list view i m showing all the folders and files, but currently all have same icon i.e of a folder. I want different icons for folder and directories. Moreover when i click on a file i want to see list of applications which can open it. Currently i m able to open a directory when clicked and when a file is clicked i show a toast unable to open.
Already thought about many thing but still unable to figure out
Any help is appreciated. Thanks in advance.
Here is my activity:
package com.rrawat.fileexplorer;
import android.app.ActionBar;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ListFileActivity extends ListActivity {
private String path;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_files);
// Use the current directory as title
path = "/sdcard";
if (getIntent().hasExtra("path")) {
path = getIntent().getStringExtra("path");
}
setTitle(path);
// Read all files sorted into the values-array
List values = new ArrayList();
File dir = new File(path);
if (!dir.canRead()) {
setTitle(getTitle() + " (inaccessible)");
}
String[] list = dir.list();
if (list != null) {
for (String file : list) {
if (!file.startsWith(".")) {
values.add(file);
}
}
}
Collections.sort(values);
// Put the data into the list
this.setListAdapter(new ArrayAdapter<String>(this,R.layout.mylist,R.id.Itemname,values));
/*ArrayAdapter adapter = new ArrayAdapter(this,
android.R.layout.simple_list_item_2, android.R.id.text1, values);
setListAdapter(adapter);*/
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
String filename = (String) getListAdapter().getItem(position);
if (path.endsWith(File.separator)) {
filename = path + filename;
} else {
filename = path + File.separator + filename;
}
if (new File(filename).isDirectory()) {
Intent intent = new Intent(this, ListFileActivity.class);
intent.putExtra("path", filename);
startActivity(intent);
} else {
Toast.makeText(this, filename + " is not a directory", Toast.LENGTH_LONG).show();
}
}
}
My xmls:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
mylist.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:orientation="horizontal" >
<ImageView
android:id="#+id/icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:src="#drawable/folder" />
<TextView
android:id="#+id/Itemname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:paddingTop="5dp"/>
</LinearLayout>
You can use this to determine if a File is a directory.
boolean isDir = new File(path).isDirectory();
You'll have to create a custom adapter and then override getView() as Bojan Kseneman said.
Right now, you are using the default implementation of ArrayAdapter, but you can create a class that extends ArrayAdapter and define it like:
public class FilesAndFoldersAdapter extends ArrayAdapter<String> {
public FilesAndFoldersAdapter(Context context, ArrayList<String> values) {
super(context, 0, values);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
String filePath = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.mylist, parent, false);
}
// Lookup view for data population
TextView tvName = (TextView) convertView.findViewById(R.id.Itemname);
ImageView ivImage = (ImageView) convertView.findViewById(R.id.icon);
// Populate the data into the template view using the data object
tvName.setText(filePath);
if (new File(filePath).isDirectory()) {
ivImage.setImageResouce(R.drawable.folder_icon);
} else {
ivImage.setImageResouce(R.drawable.file_icon);
}
// Return the completed view to render on screen
return convertView;
}
}
The important part of this code to you, is the one that checks whether the file is a directory or file and then uses the corresponding icon on the ImageView.
After creating the custom adapter class, all you have to do is set it as your ListView's adapter like so:
setListAdapter(new FilesAndFoldersAdapter(this, values));
I am currently working on a project in which I was updating a ListView's adapter from ArrayAdapter to a Custom CursorAdapter.
I deleted the R.java intentionally to regenerate the R.java file after inserting a new <string></string> to the res/string.xml file since it was not automatically regenerating. The file did not generate.
I continued to debug, and ran a Project->Clean... in attempt to regenerate the R.java file. This did not work either.
After checking StackOverflow, I also tried changing the version in AndroidManifest.xml in hope to regenerate the file. This also did not work. I've tried a few other hacks in hopes something might have Eclipse regenerate the file. No Luck.
Does anyone have any idea? I am on a tight deadline and this is really holding me back.
Here is the file I was working in when the issue arose:
package com.renaissanceartsmedia.gradingapp.controllers.fragments;
import java.util.ArrayList;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v4.util.ArrayMap;
import android.support.v4.widget.CursorAdapter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.TextView;
import com.renaissanceartsmedia.gradingapp.R;
import com.renaissanceartsmedia.gradingapp.controllers.activities.CourseActivity;
import com.renaissanceartsmedia.gradingapp.model.Course;
import com.renaissanceartsmedia.gradingapp.model.CourseStore;
import com.renaissanceartsmedia.gradingapp.model.GradingAppDatabaseHelper.CourseCursor;
public class CourseListFragment extends ListFragment {
// DEBUG
private static final String TAG = "CourseListFragment";
// Create an ArrayList<String> to store flashcards
ArrayList<Course> mCourses;
ArrayMap<Long, Course> mCoursesById;
// Cursor Object
private CourseCursor mCursor;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the Title of the Fragment's Activity
getActivity().setTitle(R.string.course_list);
// Load Cursor to DB
mCursor = CourseStore.get(getActivity()).queryCourses();
// Set the list of FlashcardListFragments
mCourses = CourseStore.get(getActivity()).getCourses();
mCoursesById = CourseStore.get(getActivity()).getCoursesById();
// Create an ArrayAdapter to use for displaying FlashcardListFragments in FlashcardListActivity
/*
ArrayAdapter<Flashcard> adapter = new ArrayAdapter<Flashcard>(
getActivity(),
android.R.layout.simple_list_item_1,
mFlashcards);
*/
// OLD METHOD
//ListItemLayoutAdapter adapter = new ListItemLayoutAdapter(mCourses);
CourseCursorAdapter adapter = new CourseCursorAdapter(getActivity(), mCursor);
// Set the adapter for the list
setListAdapter(adapter);
}
/* Handles a user selection of a FlashcardListFragment
*
*/
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
//Flashcard f = (Flashcard)(getListAdapter()).getItem(position);
// OLD WAY
//Course c = ((ListItemLayoutAdapter)getListAdapter()).getItem(position);
/*
Course c = ((CourseCursorAdapter))getListAdapter());
Log.d(TAG, c.getCourseTitle() + " was clicked");
// Start a new activity using an Intent
Intent openFlashcardDetail = new Intent(getActivity(), CourseActivity.class);
// Add EXTRAS to the intent
//openFlashcardDetail.putExtra(FlashcardFragment.EXTRA_FLASHCARD_ID, f.getId());
openFlashcardDetail.putExtra(Course.EXTRA_COURSE_ID, c.getId());
startActivity(openFlashcardDetail);
*/
}
// OLD METHOD
//class ListItemLayoutAdapter extends ArrayAdapter<Course> {
class CourseCursorAdapter extends CursorAdapter {
// Member Properties
// OLD METHOD
Course mCurrentListObject;
CourseCursor mCourseCursor;
// Constructor
// OLD METHOD
/*
public ListItemLayoutAdapter(ArrayList<Course> itemContent) {
super(getActivity(), 0, itemContent);
}
*/
public CourseCursorAdapter(Context context, CourseCursor cursor) {
super(context, cursor, 0);
mCourseCursor = cursor;
}
// OLD WAY
/*
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//If we weren't given a view, inflate a new view
if (convertView == null) {
convertView = getActivity().getLayoutInflater()
.inflate(R.layout.list_item_layout, null);
}
// Configure the view for this object
mCurrentListObject = getItem(position);
// Make Connections from Layout to Java code
TextView mainTextView = (TextView) convertView.findViewById(R.id.item_main_text);
TextView subTextView = (TextView) convertView.findViewById(R.id.item_sub_text);
// Set the Contents of the Views
mainTextView.setText(setMainText());
subTextView.setText(setSubText());
return convertView;
}
*/
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// Use a layout Inflater to get a row view
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return inflater.inflate(android.R.layout.simple_list_item_1, parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
// Get the course for the current row
Course course = mCourseCursor.getCourse();
// Setup a new TextView
TextView courseTitleTextView = (TextView)view;
String mainText = context.getString(R.string.course_title_hint, course.getCourseTitle());
courseTitleTextView.setText(mainText);
}
public String setMainText() {
return mCurrentListObject.getCourseTitle();
}
public String setSubText() {
return mCurrentListObject.getSubject();
}
}
}
I have solution, I hope this will help you. !!
Step 1) Change Build Target
For Example, if you selected 2.2 as Build Target then select Maximum you have. (like 4.4)
And if you selected 4.4 then select 4.3 as target.
Step 2) Clean Project
It will create R.java again
Thank you.
If you are on Eclipse open your problems view (Window -> Show view -> Problems) and look for an error in your resources or manifest
Try restarting eclipse, sometimes it will do the trick. Check if you are using jdk 7, it only needs jdk 6.
This usually happens because there is an issue somewhere in your XML or resource file names.
Try restarting Eclipse, if it still does not indicate where the problem is, try retracing your steps the last changes you made to XML files before this problem occurred. You will find some kind of syntax error or spelling mistake or invalid file name somewhere. Fix it then clean again.