I am working on an android application which implements Navigation drawer as its main menu then depending on the choices I do my operations. Now one of the task is to populate a listview from online mysql database host using jdbc. I am able to populate the listview in normal activity but the same code is not working in fragment. This is how my Fragment looks:
public class HomeFragment extends Fragment
{
private ProgressDialog pDialog;
ListView listView ;
Connection conn=null;
ResultSet rs=null;
PreparedStatement st=null;
List<Map<String,String>> list = new ArrayList<Map<String,String>>();
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.main_list, container, false);
try
{
initList();
} catch (SQLException e)
{
e.printStackTrace();
}
String[] from = { "sender", "subject" ,"file_name"};
int[] to = {R.id.sender,R.id.subject,R.id.file_name};
SimpleAdapter adapter = new SimpleAdapter(getActivity(),list,R.layout.list_item,from,to);
//ListView lv=(ListView) rootView.findViewById(R.id.list);
//getListView();
ListView lv= (ListView) getActivity().findViewById(R.id.list);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String sender = ((TextView) view.findViewById(R.id.sender)).getText() .toString();
String subject = ((TextView) view.findViewById(R.id.subject)).getText() .toString();
String fname = ((TextView) view.findViewById(R.id.file_name)).getText() .toString();
}
});
return rootView;
}
public void initList() throws SQLException
{
String username="sql428447";
String pass="************";
String sender,subject,file_name;
try
{
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://sql4.freesqldatabase.com:3306/sql428447",username,pass);
}
catch(Exception x)
{
x.printStackTrace();
}
try
{
String sql="select sender,subject,file_name from files";
st=conn.prepareStatement(sql);
rs=st.executeQuery();
while(rs.next())
{
sender=rs.getString(1);
subject=rs.getString(2);
file_name=rs.getString(3);
list.add(createRecord(sender, subject,file_name));
}
}
catch(Exception z)
{
z.printStackTrace();
}
finally
{
st.close();
rs.close();
}
}
public HashMap<String, String> createRecord(String key, String name,String file_name)
{
HashMap<String, String> record = new HashMap<String, String>();
record.put( "sender", key);
record.put( "subject", name);
record.put("file_name",file_name);
return record;
}
}
and I am calling this fragment from Navigation drawer select item like this:
case 1:
newFragment = new HomeFragment();
transaction.replace(R.id.content_frame, newFragment);
transaction.addToBackStack(null);
transaction.commit();
break;
But at runtime in log its throwing exception on line initlist() and st.close() which I am not able to figure out. I guess my approach is almost correct which is discussed in most tutorials but I am not understanding fault in my code cause it is working in normal activity. Any help would be appreciated. Thanks
This is the screenshot of exception
You would probably benefit from using a ListFragment, I've seen many guides on the internet assume you are using one so it can get very confusing.
As for your current error, you're dereferencing st in the finally without verifying it's not null first. If conn throws an error you'll have this happen.
try
{
String sql="select sender,subject,file_name from files";
st=conn.prepareStatement(sql);
rs=st.executeQuery();
while(rs.next())
{
sender=rs.getString(1);
subject=rs.getString(2);
file_name=rs.getString(3);
list.add(createRecord(sender, subject,file_name));
}
}
catch(Exception z)
{
z.printStackTrace();
}
finally
{
if (st != null) {
st.close();
if (rs != null) {
rs.close();
}
}
}
You should have to use ListView lv= (ListView) rootView.findViewById(R.id.list); instead of ListView lv= (ListView) getActivity().findViewById(R.id.list); ... rootView in place of getActivity()
Related
In My application i am Having Dynamic Spinners.
Totally 2 Spinners are there in a Method,Both are dependent(SPinner1 ,Spinner2).
I can call that method multiple Times.
Spinner Data Loading from Local database.
Problem:
i called that method twice So activity Shown Totally 4 Spinners.
1a.spinner1
1b.SPinner2
2a.Spinner1
2b.Spinner2
Based on 3rd Spinner what i Selected , 4th Spinner data is loading perfectly.
but based on 1st Spinner Selected item data Not showing in 2nd Spinner, because last iteration data(3rd and 4th spinner)only stored in String Array.
Please Help me to Solve this. show data in all the spinners.
My Method to create Dynamic SPinners
// Helper for inflating a row Dynamic SPINNER
private void inflateDynamic_SpinnerRow(String ObjectidTypeIdVal,final String LabelvalDynamic,String ValidationID,String SavedFormidValString
, final String FormObjectIDValue)
{
Log.i("Dynamic Spinner", LabelvalDynamic+"Form OBJECT Id"+FormObjectIDValue);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View rowView123 = inflater.inflate(R.layout.rowfor_dynamic_spinner_with_label, null);
final TextView Textview_Label1 = (TextView) rowView123.findViewById(R.id.textViewa1Labelxml);
final TextView Textview_Label2 = (TextView) rowView123.findViewById(R.id.textViewa2Labelxml);
RelativeLayoutDynamic2=(RelativeLayout) rowView123.findViewById(R.id.Realtive2);
DynamicSpinner123 = (Spinner) rowView123.findViewById(R.id.DynamicSpinner1xml);
DynamicSpinner123Dependent2=(Spinner)rowView123.findViewById(R.id.DynamicSpinner2xml);
DynamicSpinnerarr= new ArrayList<String>();
DynamicSpinnerarr_IdValue= new ArrayList<String>();
// DynamicSpinnerDependdentarr= new ArrayList<String>();
if (!LabelvalDynamic.equals(""))
{
//Converting string to Array list
try
{
MobileServiceList<th_tbdynamicspinner> results09;
results09 = mToDoTable_Form_DynamicSPinner_Table88_Local_Database.read(mPullQuery12378).get();
//Offline Sync
if(!results09.isEmpty())
{
Log.i("Data Is Available ", "From Lcoal>>>>>>" + "Data DynamicSPinner");
for (int i = 0; i < results09.size(); i++)
{
Boolean mComplete_BooleanState=results09.get(i).isComplete();
Dynamic_Spinner_ID_StringVal1_TableValue3=results09.get(i).getDynamic_Spinner_Id_StringOne();
Form_Object_ID_StringVal1_TableValue3=results09.get(i).getForm_Object_Id_StringOne();
Table_Name_StringVal1_TableValue3=results09.get(i).getTable_Name_StringOne();
ID_Column_StringVal1_TableValue3=results09.get(i).getID_Column_StringOne();
Data_Column_StringVal1_TableValue3=results09.get(i).getData_Column_StringOne();
Data_Condition_StringVal1_TableValue3=results09.get(i).getData_Condition_StringOne();
Dependent_SPinner_StringVal1_TableValue3=results09.get(i).getDependent_Spinner_StringOne();
FormID_value_StringVal1_TableValue3=results09.get(i).getFormId_Val_StringOne();
Log.i("Local Database Listview", Table_Name_StringVal1_TableValue3 + ":" + Form_Object_ID_StringVal1_TableValue3);
/* DynamicSpinnerarr.add(Dependent_SPinner_StringVal1_TableValue3);
DynamicSpinnerarr_IdValue.add(ID_Column_StringVal1_TableValue3);*/
Collections.addAll(DynamicSpinnerarr,Dependent_SPinner_StringVal1_TableValue3);
Collections.addAll(DynamicSpinnerarr_IdValue,ID_Column_StringVal1_TableValue3);
if(Dependent_SPinner_StringVal1_TableValue3.equals(""))
{
Log.i("SPINN", "Spinner Data NotFound from Local");
}
else
{
Log.i("Listview ", "Dynamic Spinner Data AVAILABLE");
String Data[]=LabelvalDynamic.split(",");
Textview_Label1.setText(Data[0].toString());
Textview_Label2.setText(Data[1].toString());
arrayadpFIrstDynamic=new ArrayAdapter<String>(Form_DetailsAddPage.this,android.R.layout.simple_spinner_dropdown_item,DynamicSpinnerarr);
arrayadpFIrstDynamic.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
DynamicSpinner123.setAdapter(arrayadpFIrstDynamic);
}
}
}
else
{
Log.i("Dyanmic SPinner ", "Data NotFound in Local");
}
} catch (Exception e)
{
e.printStackTrace();;
Log.i("Local In Listview", "Exception Occur......!");
}
}
else
{
mExclusiveEmptyView = rowView123;
//deleteButton.setVisibility(View.INVISIBLE);
Textview_Label1.setText("NOt Avilable");
}
/*Item Selected in First Dynamic Spinner :-)*/
DynamicSpinner123 .setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
#Override
public void onItemSelected(AdapterView<?> spinner123, View view, int position, long id)
{
try
{
DynamicSpinnerDependdentarr= new ArrayList<String>();
String selectedItem = spinner123.getItemAtPosition(position).toString();
for (String member : DynamicSpinnerarr)
{
Log.i("Member name: ", member);
}
DYNAMICSPINNER_VALUE_ARRAY=new String[DynamicSpinnerarr.size()];
DYNAMICSPINNER_VALUE_ARRAY=DynamicSpinnerarr.toArray(DYNAMICSPINNER_VALUE_ARRAY);
DYNAMICSPINNER_ID_VALUE_ARRAY=new String[DynamicSpinnerarr_IdValue.size()];
DYNAMICSPINNER_ID_VALUE_ARRAY=DynamicSpinnerarr_IdValue.toArray(DYNAMICSPINNER_ID_VALUE_ARRAY);
Log.i("String Selcted",selectedItem);
Log.i(" MY ARRAY Selected :-)",Arrays.toString(DYNAMICSPINNER_VALUE_ARRAY));
/*Finding the Id related to Dynamic Spinner*/
for(int i=0;i<DYNAMICSPINNER_VALUE_ARRAY.length;i++)
{
if(selectedItem.equals(DYNAMICSPINNER_VALUE_ARRAY[i]))
{
DynamicSpinnerIdString=DYNAMICSPINNER_ID_VALUE_ARRAY[i];
Log.i("DYNAMIC ID",DynamicSpinnerIdString);
// break;
}
}
/*For Getting Spinner LocalDatabase Data*/
MobileServiceList<th_tbdynamicspinnerdependenttable> results678;
results678 = mToDoTable_Form_DynamicSPinnerDependent_Table77_Local_Database.read(mPullQuery1234).get();
//Offline Sync
if(!results678.isEmpty())
{
RelativeLayoutDynamic2.setVisibility(View.VISIBLE);
Log.i("Data Is Available ", "From Lcoal>>>>>>" + "Data SPinner");
for (int i = 0; i < results678.size(); i++)
{
Boolean mComplete_BooleanState=results678.get(i).isComplete();
DyncamicDependent_ColumnIDStringVal1_TableValue2 = results678.get(i).getId_Column_StringOne();
DynamicDependent_CITYList_VALUE_StringVal1_TableValue2 = results678.get(i).getCity_List_StringOne();
Log.i("Local Database Listview", DyncamicDependent_ColumnIDStringVal1_TableValue2 + ":" + DynamicDependent_CITYList_VALUE_StringVal1_TableValue2);
Collections.addAll(DynamicSpinnerDependdentarr, DynamicDependent_CITYList_VALUE_StringVal1_TableValue2.split(","));
if(DyncamicDependent_ColumnIDStringVal1_TableValue2.equals(""))
{
Log.i("SPINN", "Spinner Data NotFound from Local");
}
else
{
Log.i("Listview ", "Spinner Data AVAILABLE");
// TextviewLabel.setText(Labelval.toString());
arrayadp2_Dependent=new ArrayAdapter<String>(Form_DetailsAddPage.this,android.R.layout.simple_spinner_dropdown_item,DynamicSpinnerDependdentarr);
arrayadp2_Dependent.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
DynamicSpinner123Dependent2.setAdapter(arrayadp2_Dependent);
}
}
}
else
{
Log.i("DynamiceSPinner ", "Dependent Data NotFound in Local");
RelativeLayoutDynamic2.setVisibility(View.GONE);
}
} catch (Exception e)
{
e.printStackTrace();
Log.i("","Spinner Error OnItemSelectedClick");
}
}
#Override
public void onNothingSelected(AdapterView<?> arg0)
{
// TODO Auto-generated method stub
}
});
DynamicSpinner123.setId(viewsCount++);
allViews.add(DynamicSpinner123);
allValidation_arr.add(ValidationID);
allObjectid_arr.add(ObjectidTypeIdVal);
allSavedformid_arr.add(SavedFormidValString);
allformObject_id_arr.add(FormObjectIDValue);
DynamicSpinner123Dependent2.setId(viewsCount++);
allViews.add(DynamicSpinner123Dependent2);
allValidation_arr.add(ValidationID);
allObjectid_arr.add(ObjectidTypeIdVal);
allSavedformid_arr.add(SavedFormidValString);
allformObject_id_arr.add(FormObjectIDValue);
// Inflate at the end of all rows
mContainerView.addView(rowView123);
}
public class DynamicSpiner extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
//main spinner data
String firstSpinnerArray[] = new String[]{"One", "Two", "Three", "Four"};
//dependent spinner data in arrays
List<String[]> dependentDataList = new ArrayList<>();
//initialize main adapter and dependent adapter
ArrayAdapter<String> adapter, adapterDependent;
//initialize main Spinner and dependent Spinner
Spinner spinner, spinnerDependent;
//creating map for dependent Spinner to load the data according to its parent spinner
HashMap<Integer, Spinner> hashMap = new HashMap<Integer,Spinner>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dynamic_spiner);
//add data in List for dependentSpinner data
dependentDataList.add(new String[]{"One-1", "One-2", "One-3", "One-4"});
dependentDataList.add(new String[]{"Two-1", "Two-2", "Two-3", "Two-4"});
dependentDataList.add(new String[]{"Three-1", "Three-2", "Three-3", "Three-4"});
dependentDataList.add(new String[]{"Four-1", "Four-2", "Four-3", "Four-4"});
adapter = new ArrayAdapter<String>(DynamicSpiner.this, android.R.layout.simple_list_item_1);
adapterDependent = new ArrayAdapter<String>(DynamicSpiner.this, android.R.layout.simple_list_item_1);
for (int i=0; i<firstSpinnerArray.length; i++){
spinner = new Spinner(DynamicSpiner.this);
spinnerDependent = new Spinner(DynamicSpiner.this);
spinner.setId(i);
spinnerDependent.setId(i);
hashMap.put(i, spinnerDependent);
spinner.setOnItemSelectedListener(this);
adapter.add(firstSpinnerArray[i]);
}
spinner.setAdapter(adapter);
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String getDependentArray[] = dependentDataList.get(position);
for(String string : getDependentArray){
adapterDependent.add(string);
}
int spinnerId = view.getId();
if(spinnerId == position){
Spinner getSpinnerDependent = hashMap.get(position);
getSpinnerDependent.setAdapter(adapterDependent);
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
I haven't not tested this. Hope it help you.
before adding views to mContainerView.addView(rowView123);
first remove the previous child views.
//snippet.
//remove all views
mContainerView.removeAllViews();
//add new views
mContainerView.addView(rowView123);
Want to understand how to use / take result from ParseQuery into a String[] not inside the query.
Here is the code:
public class OptionDialogFragment extends DialogFragment implements
AdapterView.OnItemClickListener {
String[] listitems = {here is where i want the result from the query};
ListView mylist;
TextView chosenProperty;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.option_dialog_content, null, false);
mylist = (ListView) view.findViewById(R.id.list);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ParseQuery<PropertyTypes> pt = new ParseQuery<PropertyTypes>(PropertyTypes.class);
pt.whereExists("propertyType");
pt.orderByAscending("propertyType");
pt.findInBackground(new FindCallback<PropertyTypes>() {
#Override
public void done(List<PropertyTypes> pList, ParseException e) {
if (e == null) {
for(int i = 0; i < pList.size(); i++){
// Want to take the result from here and put it in the String array above
// String array "listitems"
}
} else {
e.printStackTrace();
}
}
});
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, listitems);
mylist.setAdapter(adapter);
mylist.setOnItemClickListener(this);
}
}
There would be a direct method to do it if your List was of String, However, in your case it will depend on what the PropertyType class contains. Here's an example of what the code may looks like:
listItems = new String[pList.size()];
for(int i = 0; i < pList.size(); i++){
listItems[i]=pList.get(i).getStringObject();
}
So pList.get(i) will get you your PropertyTypes class object, you should replace getStringObject() with a getter method within PropertyTypes that return a String
Above when you declare your member variable listItems, don't initialize it
String[] listItems;
chose a JSON lib used to parse response from ParseDB. ( std JSON or Jackson are both good libs )
{"results":[{"ACL":{"_User.objectId"
Change existing 'for' iteration inside of 'done()' to handle the JSON ARRAY that is a child of 'results' you see above
ArrayNode array = (ArrayNode) root.path("results");
int i = 0;
for (JsonNode node : array) {
i++;
Foreach element of the array get the string value of the columns that you want from 'PropertyTypes'
YourCollection
myCollection.add(node.path("PTyp.property1").getTextValue());
finally...
myCollection.toArray()
above uses 'jackson' lib for Json parse
gradle depencies
compile files('libs/jackson-core-lgpl-1.9.2.jar')
compile files('libs/jackson-mapper-lgpl-1.9.2.jar')
I am having issues converting my previously working FragmentActivity and Customlistadapter to a ListFragment to be used with my navigation drawer. Currently, the navigation drawer is working correctly.
Below is the modified code for GetContacts
public class GetContacts extends android.support.v4.app.ListFragment {
// Log tag
private static final String TAG = MainActivity.class.getSimpleName();
// json URL
private static final String url = "http://url.json.php";
private ProgressDialog pDialog;
private List<Contacts> contactList = new ArrayList<Contacts>();
private ListView listView;
private ContactListAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootview = inflater.inflate(R.layout.fragment_contacts, container, false);
return rootview;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
//See the second issue about wotking with ListFragment's list.
adapter = new ContactListAdapter(this, contactList);
setListAdapter(adapter);
// pDialog = new ProgressDialog(this);
// Showing progress dialog before making http request
// pDialog.setMessage("Loading...");
//pDialog.show();
// Creating volley request obj
JsonArrayRequest contactReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
Contacts contacts = new Contacts();
contacts.setDivision(obj.getString("Division"));
contacts.setName(obj.getString("name"));
contacts.setNumber(obj.getString("number"));
// adding contacts to contacts array
contactList.add(contacts);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(contactReq);
//end volley code paste
}
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
}
Additionally, I have modified the code for ContactListAdapter. Currently I am getting the following compile error. "Error:(49, 56) error: cannot find symbol method getContext()". I checked this SO question and tried to understand what is causing this issue with no luck.
public class ContactListAdapter extends BaseAdapter {
private Activity activity;
private Fragment fragment;
private LayoutInflater inflater;
private List<Contacts> contactItems;
public ContactListAdapter(Fragment fragment, List<Contacts> contactItems) {
this.fragment = fragment;
this.contactItems = contactItems;
}
#Override
public int getCount() {
return contactItems.size();
}
#Override
public Object getItem(int location) {
return contactItems.get(location);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null){
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_rowcontacts, null);
}
TextView division = (TextView) convertView.findViewById(R.id.division);
TextView name = (TextView) convertView.findViewById(R.id.name);
TextView number = (TextView) convertView.findViewById(R.id.number);
// getting contact data for the row
Contacts m = contactItems.get(position);
// Division
division.setText(m.getDivision());
// Name
name.setText("Name: " + m.getName());
// number
number.setText("Number: " + m.getNumber());
return convertView;
}
}
The main problem is that a FragmentActivity isn't a Fragment, is an Activity (see the reference here). You can't instantiate it as a Fragment like you do in selectItem().
If you want contacts to be loaded in your main activity (the one with the navigation drawer) then GetContacts should inherit from Fragment instead of FragmentActivity.
UPDATE
There are three issues with your code.
Null pointer exception (setting the adapter in the right place)
First you should move everything related to setting up the adapter to a method that is called after the Fragment is attached to its Activity (more info about the Fragment's lifecycle here). In onCreateView the Activity hasn't attached the Fragment yet so the Context of the adapter won't be available (see the third issue). Override onAttach() and place it there:
public class GetContacts extends ListFragment {
// Log tag
private static final String TAG = MainActivity.class.getSimpleName();
// json URL
private static final String url = "http://url.json.php";
private ProgressDialog pDialog;
private List<Contacts> contactList = new ArrayList<Contacts>();
private ListView listView;
public ContactListAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_contacts, container, false);
return rootView;
}
#Override
public void onAttach(Activity activity) {
//See the third issue about the Context passed to the adapter.
adapter = new ContactListAdapter(activity, contactList);
//See the second issue about working with ListFragment's list.
setListAdapter(adapter);
// pDialog = new ProgressDialog(this);
// Showing progress dialog before making http request
// pDialog.setMessage("Loading...");
//pDialog.show();
// Creating volley request obj
JsonArrayRequest contactReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
Contacts contacts = new Contacts();
contacts.setDivision(obj.getString("Division"));
contacts.setName(obj.getString("name"));
contacts.setNumber(obj.getString("number"));
// adding contacts to contacts array
contactList.add(contacts);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(mcontactReq);
//end volley code paste
}
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
}
Null pointer exception (working with ListFragment's list
ListFragments provide some methods like setListAdapter() to work with the inner ListView without having to get it first with findViewById(), but they work with their "default" ListView. For identifying this ListView they look in the layout for a ListView with the id #id/android:list. You're using a custom id for your ListView so setListAdapter() cannot find the default ListView (more info about ListFragment here). You have three posible solutions:
First:
If your layout doesn't contain more than a ListView you don't have to use a custom layout. Don't override onCreateView, removing everything about inflating a custom view.
Second:
Change the id of your ListView to #id/android:list in the xml layout file.
Third:
Maintain your custom layout and id, but always use the ListView getting it first with findViewById(), not with the ListFragment's methods for dealing with lists (like when GetContacts was a FragmentActivity). So this:
listView = (ListView) rootView.findViewById(android.R.id.list);
adapter = new ContactListAdapter(this, contactList);
setListAdapter(adapter);
would become this:
listView = (ListView) getView().findViewById(android.R.id.list);
adapter = new ContactListAdapter(this, contactList);
listView.setListAdapter(adapter);
The first two allow you to work with the default list. I don't recomend you to go for the third, since ListFragments are designed for helping you in dealing with lists faster and you wouldn't be using their helper methods, and therefore using a ListFragment like any other Fragment.
P.S. The code for GetContacts I posted before use the second solution.
LayoutInflater in Adapter
With BaseAdapter you have to keep a reference of the Context in wich the adapter will work. Since Fragment isn't a Context, fragments have to use the Activity they're attached to as the Context. Look a this line in the GetContact's code I just updated (in GetContact's onAttached()):
adapter = new ContactListAdapter(activity, contactList);
Then in the adapter you use that as the Context to get the LayoutInflater:
public class ContactListAdapter extends BaseAdapter {
//There is no need for this two
//private Activity activity;
//private Fragment fragment;
//We use this instead
private Context context
private LayoutInflater inflater;
private List<Contacts> contactItems;
//Now the constructor receives a Context
public ContactListAdapter(Context context, List<Contacts> contactItems) {
this.context = context;
this.contactItems = contactItems;
}
//Every other method remains the same
...
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//Now we use context to get the LayoutInflater
if (convertView == null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_rowcontacts, null);
}
//The rest of the code is the same
...
}
}
EDIT
Added the changed code for the "set up the adapter in the right place".
Changed the third issue for using a BaseAdapter (I got confused).
Okay, I have searched threw here and did not find my answer at all. What my android app is suppose to be doing is get a list from my php & mysql server, then store it on the database on the phone. This all works, and I can even create a listview with the information from my sqlite db. Where I am stuck as a new coder is trying to figure out how to display the information when they click on the listview item that will take them to another page that will show all the details for that listview.
So in short what I want is have my listview, items 1,item 2, item 3 for example, then when they click item 2, it gets the information for item 2 and displays it. Can someone point me in the correct direction, i know i have to use setOnClickListener, but just unsure how to make it look for that certain item.
public class Events extends Activity
{
// Identifies a particular Loader being used in this component
String event_name, event_time, event_price, event_loc;
static JSONObject object =null;
DBAdapter myDb;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.events);
openDB();
new PrefetchData().execute();
// used to refresh my page.
Button button = (Button) findViewById(R.id.refresh);
button.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
openDB();
new PrefetchData().execute();
}
});
}
#Override
protected void onDestroy()
{
super.onDestroy();
closeDB();
}
private void openDB()
{
myDb = new DBAdapter(this);
myDb.open();
}
private void closeDB()
{
myDb.close();
}
private class PrefetchData extends AsyncTask<Void, Void, Void>
{
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0)
{
myDb.deleteAll();
JsonParser jsonParser = new JsonParser();
String json = jsonParser.getJSONFromUrl("http://www.website.com/test.json");
Log.e("JSON Response: ", "> " + json);
if (json != null)
{
try
{
JSONObject parent = new JSONObject(json);
JSONArray eventDetails = parent.getJSONArray("event");
for(int i=0; i < eventDetails.length(); i++)
{
object = eventDetails.getJSONObject(i);
event_name = object.getString("event_name");
event_time = object.getString("event_time");
event_price = object.getString("event_price");
event_loc = object.getString("event_loc");
//event_pic = object.getString("event_pic");
myDb.insertRow(event_name,event_time,event_price,event_loc);
Log.e("JSON", "> " + event_name + event_time + event_price + event_loc );
}
} catch (JSONException e)
{
// TODO Auto-generated catch block
Log.e("Json Error", "Error: " + e.toString());
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
populateListViewFromDB();
myDb.close();
// After completing http call
// will close this activity and lauch main activity
//Intent i = new Intent(MainActivity.this, Events.class);
//i.putExtra("event_name", event_name);
//i.putExtra("event_time", event_time);
//i.putExtra("event_price", event_price);
//startActivity(i);
// close this activity
//finish();
}
}
#SuppressWarnings("deprecation")
private void populateListViewFromDB()
{
Cursor cursor = myDb.getAllRows();
// Allow activity to manage lifetime of the cursor.
// DEPRECATED! Runs on the UI thread, OK for small/short queries.
startManagingCursor(cursor);
// Setup mapping from cursor to view fields:
String[] fromFieldNames = new String[]
{DBAdapter.KEY_NAME, DBAdapter.KEY_TIME, DBAdapter.KEY_PRICE, DBAdapter.KEY_LOC};
int[] toViewIDs = new int[]
{R.id.item_name};//, R.id.item_time};//, R.id.item_price, R.id.item_loc};
// Create adapter to may columns of the DB onto elemesnt in the UI.
SimpleCursorAdapter myCursorAdapter =
new SimpleCursorAdapter(
this, // Context
R.layout.item_layout, // Row layout template
cursor, // cursor (set of DB records to map)
fromFieldNames, // DB Column names
toViewIDs // View IDs to put information in
);
// Set the adapter for the list view
ListView myList = (ListView) findViewById(R.id.listViewfordb);
myList.setAdapter(myCursorAdapter);
}
}
Don't use the setOnClickListener.
Be sure to use a CursorAdapter and to specify an ID column inside your db.
when you set the protected void onListItemClick(ListView l, View v, int position, long id) automatically the id is the ID inside the db. this way you can pass it through an intent and use the id to get back the data from the db.
Hope it's clear enough. Sorry i wrote quite in a rush
from your code simply add
myList.setOnItemClickListener(
new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> arg0, View view,
int position, long id) {
//here the id value is what you need to take data from the db filtering by id
}
}
);
you should set listeners to your ListView something like this
private OnItemClickListener onListItemClickListener = new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
// TODO YOUR CODE
}
};
private OnItemLongClickListener onItemLongClickListener = new OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> adapter, View view, int position, long id) {
YOUR_CODE
}
};
those are two types, longClicj and just click, you can use it both or one, its depends on your needs
also on your onCreate method you should set the listeners to your listView
listView.setOnItemClickListener(onListItemClickListener);
listView.setOnItemLongClickListener(onItemLongClickListener);
I'm beginner in Android Development!
I'm trying insert into Fragment parsing data
Trying to fix error but I have an error "
output cannot be resolved to a variable"
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
ProgressDialog mProgressDialog = new ProgressDialog(getActivity());
mProgressDialog.setCancelable(false);
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressDialog.setMessage("Загрузка данных");
mProgressDialog.show();
new ParseSite().execute("http://www.babyblog.ru/magazine/");
View view = inflater.inflate(R.layout.magazine, container, false);
ListView listview = (ListView) view.findViewById(R.id.listViewData);
listview.setAdapter(new ArrayAdapter<String>(getActivity().getApplicationContext(),
android.R.layout.simple_list_item_1 , output));
return view;
}
private class ParseSite extends AsyncTask<String, Void, List<String>> {
protected List<String> doInBackground(String... arg) {
List<String> output = new ArrayList<String>();
try
{
HtmlHelper hh = new HtmlHelper(new URL(arg[0]));
List<TagNode> links = hh.getLinksByClass("razdel-name");
for (Iterator<TagNode> iterator = links.iterator(); iterator.hasNext();)
{
TagNode divElement = (TagNode) iterator.next();
output.add(divElement.getText().toString());
}
}
catch(Exception e)
{
e.printStackTrace();
}
return output;
}
}
}
The variable 'output' has not been defined.
i.e.
listview.setAdapter(new ArrayAdapter<String>(getActivity().getApplicationContext(),
android.R.layout.simple_list_item_1 , output));
That variable is not in scope.
You attemot to use it in onCreate of your fragment, but it is declared in the ASyncTask class.
You need to go and read about ASyncTasks and how you work with them.
http://developer.android.com/guide/components/processes-and-threads.html#WorkerThreads
as a shortcut, try this:
public class YourFragment extends Fragment {
ListView listview;
#Override
public View onCreateView(
// other stuff
listview = (ListView) view.findViewById(R.id.listViewData);
// remove the setAdapater line
}
private class ParseSite extends AsyncTask<String, Void, List<String>> {
// other stuff
protected void onPostExecute(List<String> result) {
listview.setAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1 , output));
}
}
Your output variable is still null. You have to implement onPostExecute(List result) in your AsyncTask.
This will give you the output you want.
this blogpost can explain how AsyncTask works. But be careful, AsyncTask has a couple of hidden pitfalls. Read all about that here