ListView not displaying anything in new activity using array adapter - android

I've got a class that should, theoretically, display RSS headlines, from a SINGLE RSS feed site, in a ListView called searchListView. If the ListView is empty a TextView appears informing the user that the ListView is empty, which is what happens every time I navigate to this activity. The button and EditText is for filtering the headlines.
I've got the exact same class in another project (this class is the main activity in said project) which works perfectly fine.
RssItem is a class that parses the RSS feed information into a headline title and URL to the headline.
Note: SearchActivity is not the main activity.
Edit: I'm using a CallBack and LoaderManager in the main activity to display items in a list view as well. I'm not too knowledgeable about these and I really don't know if they might be causing the issue due to the main activity. I do not pass any information from the main activity, though.
FIXED: I wasn't getting any errors or anything but, for some reason, nothing would get displayed. Then I went into the android manifest and realised that the app doesn't have permissions to connect to the internet. Silly mistake, easy to miss.
<uses-permission android:name="android.permission.INTERNET"/>
SearchActivity.java
public class SearchActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<RssItem>> {
private EditText mEditText;
private Button mButton;
private ArrayAdapter<RssItem> mAdapter;
private ListView mListView ;
// hard wire Rss feed source for the time being
private String mDataSource = "http://feeds.bbci.co.uk/news/uk/rss.xml";
// no search string at the moment
private String mSearchString = "";
private static final int LOADER_ID = 1;
// The callbacks through which we will interact with the LoaderManager.
private LoaderManager.LoaderCallbacks<List<RssItem>> mCallbacks;
private LoaderManager mLoaderManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mButton = (Button) findViewById(R.id.button);
mEditText = (EditText)findViewById(R.id.editTextSearch);
mAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
mListView = (ListView)findViewById(R.id.searchListView);
mListView.setAdapter(mAdapter);
TextView emptyText = (TextView)findViewById(R.id.textViewEmpty);
mListView.setEmptyView(emptyText);
// Set list view item click listener
mListView.setOnItemClickListener(new ListListener(this));
// The Activity (which implements the LoaderCallbacks<Cursor>
// interface) is the callbacks object through which we will interact
// with the LoaderManager. The LoaderManager uses this object to
// instantiate the Loader and to notify the client when data is made
// available/unavailable.
mCallbacks = this;
// Initialize the Loader with id '1' and callbacks 'mCallbacks'.
// If the loader doesn't already exist, one is created. Otherwise,
// the already created Loader is reused. In either case, the
// LoaderManager will manage the Loader across the Activity/Fragment
// lifecycle, will receive any new loads once they have completed,
// and will report this new data back to the 'mCallbacks' object.
mLoaderManager = getLoaderManager();
mLoaderManager.initLoader(LOADER_ID, null, mCallbacks);
}
// handler for search button click
public void onClick(View v){
mSearchString = mEditText.getText().toString();
mLoaderManager.restartLoader(LOADER_ID, null, mCallbacks);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public Loader<List<RssItem>> onCreateLoader(int id, Bundle args) {
RssLoader loader = new RssLoader(
this, // context
mDataSource, // URL of Rss feed
mSearchString // search loaded RssItem for match in title
);
return loader;
}
#Override
public void onLoadFinished(Loader<List<RssItem>> loader, List<RssItem> data) {
mAdapter.clear();
mAdapter.addAll(data);
}
#Override
public void onLoaderReset(Loader<List<RssItem>> loader) {
mAdapter.clear();
}
}
ListListener.java
public class ListListener implements OnItemClickListener {
// And a reference to a calling activity
// Calling activity reference
Activity mParent;
/** We will set those references in our constructor.*/
public ListListener(Activity parent) {
mParent = parent;
}
/** Start a browser with url from the rss item.*/
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
// We create an Intent which is going to display data
Intent i = new Intent(Intent.ACTION_VIEW);
// We have to set data for our new Intent;
i.setData(Uri.parse(((RssItem)(parent.getItemAtPosition(pos))).getLink()));
// And start activity with our Intent
mParent.startActivity(i);
}
}

I wasn't getting any errors or anything but, for some reason, nothing would get displayed. Then I went into the android manifest and realised that the app doesn't have permissions to connect to the internet. Silly mistake, easy to miss.
<uses-permission android:name="android.permission.INTERNET"/> was missing.

Related

How get value from adapter class to activity Class

I am having adapter class, In that, I need to pass invoiceId to an Activity Class. I have seen some example like pass-through interface, but I lost track on following the code procedure.
Here Is My Adapter Class extends BaseAdapter
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
companyName = ct.getSharedPreferences("prefs", 0);
Log.d("test", "" + deliveryListBeans.size());
LayoutInflater inflater = (LayoutInflater) ct.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.list_vew_for_delivery_order, null);
TextView invoice = (TextView) v.findViewById(R.id.invoice);
final TextView delivery = (TextView) v.findViewById(R.id.do_delivery);
final DeliveryListBean dlb = deliveryListBeans.get(position);
invoice.setText(dlb.getInvoiceNo());
}
delivery.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ct.startActivity(new Intent(ct, EmployeesListForPopUp.class));
DeliveryOrdersListAdapter deliveryOrdersListAdapter=new DeliveryOrdersListAdapter(EmployeesListForPopUp.this);
}
});
}
Here is My Activity Class
public class EmployeesListForPopUp extends Activity {
private List<EmployeeIdNameBean> employeeIdNameBeans = new ArrayList<EmployeeIdNameBean>();
ListView listView;
SharedPreferences companyName;
EmployeePopUpAdapter employeePopUpAdapter;
private ImageView img1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_employees_list_for_pop_up);
I need to get invoiceId from Adapter Class. How?
You need to pass context of the activity in adapters constructor.
Then set activity.invoiceid value in clickevents of adapter.
One simple way is that you write a method in MainActivity
public void setInvoiceId(int invoiceId) {
// do what you want with invoiceId
}
and pass the instance of your activity to adapter
DeliveryOrdersListAdapter adapter = new DeliveryOrdersListAdapter(EmployeesListForPopUp.this);
and get it in your adapter and keep it
EmployeesListForPopUp myActivity;
public MyAdapter(EmployeesListForPopUp activity) {
myActivity = activity;
}
and where you need to pass invoiceId just call the method of main activity
myActivity.setInvoiceId(invoiceId);
General way of implementing it:
In the adapter class, where you set text to invoice TextView, you also can add a tag to it. Put attention - despite every item in the list is build from the same prototype, the tag (as well as text) will be uniq. The best way is to use "position" as value of the tag: invoice.setText(dlb.getInvoiceNo());
invoice.setTag(Integer.valueOf(position).toString());
You need to make your items in the list clickable (this is out of the scope of this question). So, when you click on some item - you can retrieve any data it has, and specifically tag - getTag();.
Then you send Intent to other activity, providing the tag as extra message. So that activity will "know" which item in the array list it is related to (i.e. tag == position, right?). And continue from there.
I implemented simple project that illustrates it. This project is simple demo and illustration of working with ArrayList adapter,
displaying the item in the ListView, clicking on some item and display relevant data in separated activity. Please download it and try (min API 21). Basic description is available in README file.
The project is here on the GitHub:
(corrected path)
https://github.com/everall77/ArrayListSimpleExmpl

Android programming: I cant get data to reload into arrayadapter

I am still stuck with this issue, can anyone help. It seems that my problem is that I cant update the data list. I have tried every solution that I've searched for on google etc.. but half the time i'm not even sure that I'm doing the correct thing.
I've used the onResume() to call notifyDataSetChanged, it didn't work. I've tried putting a refresh method into the adapter which i then called in OnResume(). Again it didn't work. Some people suggest clearing the adpater (adapter.clear();) in onResume and then using the addAll() function to relist the data but nothing works.
There has to be a simple solution to this. I have literally been stuck on this for 2 days now. very frustrated.
Here's my Fragment code again...
enter code here
public class SavedAppFragment extends ListFragment {
private static final String TAG = "AppClicked"; //DEBUGGER
private ArrayList<App> mSavedApps;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Populate the ArrayList
mSavedApps = SavedAppData.get(getActivity()).getApps();
AppAdapter adapter = new AppAdapter(mSavedApps);
setListAdapter(adapter);
}
//LIST ITEM CLICKED: /*Control what happens when list item is clicked: I.E. Load up a quiz while putting an EXTRA key containg the package name of the App to be launhced should the user get the question correct */ #Override public void onListItemClick(ListView l, View v, int position,long id) { //Return the crime for the list item that was clicked App c = ((AppAdapter) getListAdapter()).getItem(position); Log.d(TAG, "was clicked");
//Start the Activity that will list the detail of the app
Intent i = new Intent(getActivity(), Quiz_Activity.class);
String name = c.getPackage();
i.putExtra("packagename", name);
startActivity(i);
}
private class AppAdapter extends ArrayAdapter {
private ArrayList<App> mSavedApps;
public AppAdapter(ArrayList<App> apps) {
super(getActivity(), 0, apps);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//If we weren't given a view, inflate one
if (null == convertView) {
convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_app, null);
//((AppAdapter) getListAdapter()).notifyDataSetChanged();
}
((AppAdapter) getListAdapter()).notifyDataSetChanged();
//Configure the view for this crime
App c = getItem(position);
TextView nameTextView = (TextView) convertView.findViewById(R.id.app_name);
nameTextView.setText(c.getName());
// nameTextView.setText(applicationInfo.loadLabel(packageManager));
TextView packageTextView = (TextView) convertView.findViewById(R.id.app_package);
packageTextView.setText(c.getPackage());
CheckBox appCheckBox = (CheckBox) convertView.findViewById(R.id.app_checked);
appCheckBox.setChecked(c.isChecked());
//Return the view object to the ListView
return convertView;
}
}
}
THANKS!!!
When you return to Activity B, the previous Activity B hasn't been destroyed. Thus, it skips the onCreate. Move all of the stuff you want to make sure happens every time into the onResume. I think you want to make your Adapter a class variable (I'll call it mAdapter) in onCreate, and add code that will get data from the list directly. If you need to do something, put a "refresh" function in the adapter. I'm assuming you have a custom Adapter, because I've never heard of AppAdapter. If you don't, then extend AppAdapter and add that functionality. Thus, your onCreate should look like this:
mAdapter = new AppAdapter(mSavedApps);
setListAdapter(mAdapter);
Your onRefresh could update the data contained in the adapter by some new update function, like so:
mAdapter.update(SavedAppData.get(getActivity()).getApps());

ListView after click and back List is empty

I have a layout with a ListView and ImageView. Initially, ImageView is invisible. I have a list, when an Item is clicked, it shows the Image of that item by setting ImageView and making it visible and listView is invisible, so far everything is ok. From there, onBackPressed() I want to see my listview again, I override onBackPressed(), to make my image view invisible and listview visible. However, when I select an item and see the image of it then press back, a blank activity comes, not my listView. I don't want to call the activity again, what should I do? What is wrong about listView? I tried to call invalidate() and invalidateViews(), setting adapter again, but they aren't woring.
Actually I'm filing adapter in the onResume of the activity, here is the code:
public class MyViewActivity extends Activity{
ListView imageList;
CustomImageListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_list_view);
//initialization of image array list etc
}
#Override
public void onResume(){
super.onResume();
imageList = (ListView) findViewById(R.id.listView);
adapter = new CustomImageListAdapter(this,R.layout.image_item, imageNames);
imageList.setAdapter(adapter);
imageList.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> adapter, View view, int i,
long l) {
// TODO Auto-generated method stub
if(imageNames.get(i) != null) {
onImageSelected(i);
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.image_list_view, menu);
return true;
}
public void onImageSelected(int position) {
...
}
#Override
public void onBackPressed() {
if (img.getVisibility() == ImageView.VISIBLE){
// img.setVisibility(ImageView.INVISIBLE);
// imageList.invalidateViews();
// imageList.setVisibility(ListView.VISIBLE);
// Here actually I want to use the upper part that I commented, but it didn't work, I have to call the same activity again to see my listview
Intent i = new Intent(MyViewActivity.this, MyViewActivity.class);
startActivity(i);
finish();
}
else {
....
}
return;
}
private class CustomImageListAdapter extends ArrayAdapter<String>{
...
}
As long as I can guess, the problem is caused by
img.setVisibility(ImageView.INVISIBLE);
You can try to use View.GONE instead.
The difference is clearly stated in android api's doc and I quoted:
/**
* This view is invisible, but it still takes up space for layout purposes.
*/
public static final int INVISIBLE = 0x00000004;
/**
* This view is invisible, and it doesn't take any space for layout
*/
public static final int GONE = 0x00000008;
By the way, I will recommend to use fragments to do your job. Specifically, a fragment A to present the listview, and when an item is clicked, switch to fragment B which contains the content. When Back is pressed, just let the backstack do its job.
Intent i = new Intent(MyViewActivity.this, MyViewActivity.class);
i.putExtra("currentObjectID",objectID);
startActivity(i);
finish();
Why are you traversing within the same activity? You should understand the use of intents ,If you want to stay within the same activity , Just set a flag for currentObjectID instead of put Extra..

Convert ActivityGroup to Fragment

I am trying to convert my entire project from using ActivityGroups to using Fragments.
Here is my old code :
SettingsActivityGroup
public class SettingsActivityGroup extends ActivityGroup
{
// Keep this in a static variable to make it accessible for all the nested activities, lets them manipulate the view
public static SettingsActivityGroup group;
// Need to keep track of the history if you want the back-button to work properly, don't use this if your activities requires a lot of memory.
private ArrayList<View> history;
// Window focus changed listener
public OnActivityGroupViewChanged activityGroupViewChangedListener = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Allocate history
this.history = new ArrayList<View>();
// Set group
group = this;
// Start root (first) activity
Intent myIntent = new Intent(this, SettingsActivity.class); // Change to the first activity of your ActivityGroup
myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
ReplaceView("SettingsActivity", myIntent);
}
SettingsActivity
public class SettingsActivity extends Activity
{
String[] settingsLabels = {"Viderestilling", "Voicemail", "Vis nummer",
"Kø styring", "Optag samtaler", "Services" };
ListView lv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings);
lv = (ListView) findViewById(R.id.SettingsLV);
lv.setTextFilterEnabled(true);
populateListView();
}
private void populateListView()
{
lv.setAdapter(new ArrayAdapter<String>(this, R.layout.settings_items, R.id.settings_item_label, settingsLabels));
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
{
// SwitchActivity(position);
}
});
}
If I want to extend ListFragment instead of Activity - What do I need to change to make sure that everything still works ?
Have you looked at the Developer Guide article on Fragments? I think it very nearly describes your exact use case (an array-backed list in one fragment and the detail in another). And do check out the complete sample implementation in APIDemos. There's even a backward-compatible version in API 4+ Support Demos.

Android app - how to display a list of items and make them clickable

I need to display a list of text items to the screen and make them clickable. So it would be something like a list of links on a web application.
How can I do that in an Android Activity screen?
It would be some random number of items that I have to pull from a db and display all as links.
Any idea how that can be done?
You should read the doc about ListActivity, ListView and follow the Hello ListView tutorial.
Yes you can do it. Create a DataExchange class to fetch it from Db..
Store the Strings in an Array.
Create a ArrayAdapter to display the array of Strings you got from the database.
for Example
public class AndroidListViewActivity extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// storing string resources into Array
String[] numbers = {"one","two","three","four"}
// here you store the array of string you got from the database
// Binding Array to ListAdapter
this.setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, R.id.label, numbers));
// refer the ArrayAdapter Document in developer.android.com
ListView lv = getListView();
// listening to single list item on click
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// selected item
String num = ((TextView) view).getText().toString();
// Launching new Activity on selecting single List Item
Intent i = new Intent(getApplicationContext(), SingleListItem.class);
// sending data to new activity
i.putExtra("number", num);
startActivity(i);
}
});
}
}
The secondActivity to display the Particular item you have clicked should be
public class SingleListItem extends Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.single_list_item_view);
TextView txtProduct = (TextView) findViewById(R.id.product_label);
Intent i = getIntent();
// getting attached intent data
String product = i.getStringExtra("number");
// displaying selected product name
txtProduct.setText(product);
}
}
you have to create various layout files accordingly..
Hope this helps you :)
You should use a ListView. It's very simple, just create a ListActivity, put your items inside an Adapter and then set it as the Adapter of your ListActivity.
You can read more about ListViews here
There is also a new paradigm called ListFragment.
I have used ListViews before but prefer the fragments approach now - it's just very straight forward and quite flexible esp on tablets since the interation with another area on the screen when selecting an item is quite flexible and only requires very little code.
Just one example:
public class Select_FoodCategories_Fragment extends android.app.ListFragment {
private static final boolean DEBUG = true;
#Override
public void onCreate(Bundle savedInstanceState) {
if (DEBUG)
Log.i(this.getClass().getSimpleName(), " ->"
+ Thread.currentThread().getStackTrace()[2].getMethodName());
super.onCreate(savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (DEBUG)
Log.i(this.getClass().getSimpleName(), " ->"
+ Thread.currentThread().getStackTrace()[2].getMethodName());
HoldingActivity a = (HoldingActivity) getActivity();
//accessing a variable of the activity is easy
a.visibleListViewInFragment = getListView();
List<XYZ> listTodisplay = a.getListToDisplay();
MyAdapter adapter = new MyAdapter(
getActivity(), 0, listTodisplay);
setListAdapter(adapter);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
if (DEBUG)
Log.i(this.getClass().getSimpleName(), " ->"
+ Thread.currentThread().getStackTrace()[2].getMethodName());
XYZ item = (XYZ) getListAdapter()
.getItem(position);
}
}
More info here: http://developer.android.com/reference/android/app/ListFragment.html
By the way, I find it really worth it to get familiar with the new fragments concept - it just makes live much easier - esp on tablets!
ps I left the debug statements in on purpose - since it helps alto to understand the whole concept much faster in my experience

Categories

Resources