When i am trying to call the method "refresh" of main activity from another Api class,the method was called and also it shows some fatal errors.And it didn't change the adapter values.Can anyone give any idea to clear that.?
package com.example.hotspot;
import com.example.hotspot.HotspotApi;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.ListView;
import android.widget.TextView;
public class HotSpot extends Activity {
TextView textview;
ListView listview;
HotspotAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hot_spot);
textview = (TextView) findViewById(R.id.textView1);
listview = (ListView) findViewById(R.id.listView1);
adapter = new HotspotAdapter(this);
listview.setAdapter(adapter);
new HotspotApi(adapter).execute();
}
public void refresh() {
System.out.println("refresh() is called");
adapter.notifyDataSetChanged();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.hot_spot, menu);
return true;
}
}
hotspot.java
package com.example.hotspot;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.example.hotspot.HotspotModel;
import com.example.hotspot.HotspotAdapter;
import android.os.AsyncTask;
public class HotspotApi extends AsyncTask<Void, Integer, Void> implements
Icommon {
public Boolean IsServerErr = false;
private JSONArray response_array;
String url = "some url";
HotspotAdapter adapter;
HotSpot hot;
public HotspotApi(HotspotAdapter adapter) {
this.adapter = adapter;
}
#Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
getresult();
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
hot=new HotSpot();
hot.refresh();
super.onPostExecute(result);
}
void getresult() {
InternetManager manager = new InternetManager(url);
String category_jsonresponse = manager.URLRequest();
if (!manager.IsServerConn) {
IsServerErr = true;
}
if (category_jsonresponse != null) {
System.out.println("Hotspot_jsonresponse" + category_jsonresponse);
try {
response_array = new JSONArray(category_jsonresponse);
for (int i = 1; i < response_array.length(); i++) {
JSONObject image_object = response_array.getJSONObject(i);
HotspotModel h = new HotspotModel();
h.setId(image_object.getString("id") == null ? ""
: image_object.getString("id"));
h.setContent(image_object.getString("content") == null ? ""
: image_object.getString("content"));
h.setImg(image_object.getString("img") == null ? ""
: image_object.getString("img"));
h.setName(image_object.getString("name") == null ? ""
: image_object.getString("name"));
arraylist.add(h);
}
System.out.println("HotspotModelsize() is " + arraylist.size());
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
HotspotAdapter.java
package com.example.hotspot;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class HotspotAdapter extends BaseAdapter implements Icommon{
private TextView textview;
private View view;
ImageView imageview;
private LayoutInflater inflater;
public HotspotAdapter(Context context ){
inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return arraylist.size();
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return arraylist.get(arg0);
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
if (arg1 == null) {
view = inflater.inflate(R.layout.custom_layout, null);
} else {
view = arg1;
}
textview = (TextView) view.findViewById(R.id.txt_content);
textview.setText(arraylist.get(arg0).getName());
return view;
}
}
In your HotSpotApi class you are creating a new HotSpot activity, this seems wrong. I guess that you are getting json data from internet and load it into a listview.
Solution:
In HotspotApi change following instead of calling activity method:
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
adapter.notfiyDatasetChanged();
}
Hope this will help you.
hot=new HotSpot(); ?? you cannot use like that! HotSpot is an activity, should be called by Framework for example, activitymanager. Or use startActivity() to show a activity.
Refresh method (adapter.notifyDataSetChanged();) will result in refresh of UI. However, hot = new HotSpot() will not call onCreated() method,which means the UI is not created. So it definitely results in the fatal error.
I'd never see anyone call an Activity with new operator.
You should reference the common process about how use a activity and adapter.
Related
So, I am starting an AsyncTask when activity starts. I am trying to implement infinite listview. When user scrolls to the bottom of listview, an AsyncTask should start to bring new data. Meanwhile, If user scrolls up and scrolls down again to the bottom, this is where i get error.
Following is the code I tried:
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.SearchView.OnQueryTextListener;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;
public class CaseListingActivity extends ActionBarActivity {
ListView mListViewCase;
ArrayList<CaseDetails> mArrayList;
CaseListAdapter mCaseListAdapter;
View mView;
CaseListingTask mCaseListingTask;
int preLast;
int currentPage = 1;
public static final String URL = "http://xxxxxx.xxxxxxx/DC.svc/rest/GetSubject?PageNo=";
public static final String GET_SUBJECT_RESULT = "GetSubjectResult";
public static final String ID = "Id";
public static final String SUB = "Sub";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_case_listing);
mArrayList = new ArrayList<CaseDetails>();
mCaseListAdapter = new CaseListAdapter(this, mArrayList);
mCaseListingTask = new CaseListingTask();
mView = ((LayoutInflater) this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
R.layout.listview_footer, null, false);
mListViewCase = (ListView) findViewById(R.id.listViewCaseListing);
mListViewCase.addFooterView(mView);
mListViewCase.setAdapter(mCaseListAdapter);
mListViewCase.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
// if (scrollState == SCROLL_STATE_IDLE) {
// if (mListViewCase.getLastVisiblePosition() >= mListViewCase
// .getCount() - 1 - 1) {
//
// // if (mCaseListingTask.getStatus() !=
// AsyncTask.Status.RUNNING) {
// //
// // }
// if (mCaseListingTask.getStatus() == AsyncTask.Status.RUNNING)
// {
// // Do Something?
// } else {
// currentPage++;
// // load more list items:
// mCaseListingTask.execute(URL + currentPage);
// }
// }
// }
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
switch (view.getId()) {
case R.id.listViewCaseListing:
// Make your calculation stuff here. You have all your
// needed info from the parameters of this function.
// Sample calculation to determine if the last
// item is fully visible.
final int lastItem = firstVisibleItem + visibleItemCount;
if (lastItem == totalItemCount) {
// if (preLast != lastItem) { // to avoid multiple calls
// // for last item
// Log.d("Last", "Last");
// preLast = lastItem;
if (mCaseListingTask.getStatus() == AsyncTask.Status.FINISHED) {
currentPage++;
// load more list items:
mCaseListingTask.execute(URL + currentPage);
}
// }
}
}
}
});
mListViewCase.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
Toast.makeText(getBaseContext(),
arg0.getItemAtPosition(arg2).toString(),
Toast.LENGTH_SHORT).show();
}
});
new CaseListingTask().execute(URL + currentPage);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
getMenuInflater().inflate(R.menu.menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat
.getActionView(searchItem);
searchView.setOnQueryTextListener(new OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String arg0) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean onQueryTextChange(String arg0) {
// TODO Auto-generated method stub
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
public class CaseListingTask extends AsyncTask<String, Void, String> {
ProgressDialog mProgressDialog;
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
String result = "";
for (String string : params) {
result = new JSONParser().getJSONFromUrl(string);
}
return result;
}
/*
* (non-Javadoc)
*
* #see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
try {
JSONObject mJsonObject = new JSONObject(result);
JSONArray mJsonArray = mJsonObject
.getJSONArray(GET_SUBJECT_RESULT);
for (int i = 0; i < mJsonArray.length(); i++) {
JSONObject c = mJsonArray.getJSONObject(i);
mArrayList.add(new CaseDetails(c.getInt(ID), c
.getString(SUB)));
}
mCaseListAdapter.notifyDataSetChanged();
mListViewCase.removeFooterView(mView);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
* (non-Javadoc)
*
* #see android.os.AsyncTask#onPreExecute()
*/
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
// mProgressDialog = ProgressDialog.show(CaseListingActivity.this,
// "Please Wait...", "Loading...", true, false);
mListViewCase.addFooterView(mView, null, false);
}
}
}
If you need more details, please ask for it. Thanks.
The problem is simple: You can execute every AsyncTask only once. From the documentation of AsyncTask:
There are a few threading rules that must be followed for this class
to work properly:
The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
The task instance must be created on the UI thread.
execute(Params...) must be invoked on the UI thread.
Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually.
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
You create a new instance of CaseListingTask in onCreate() and try to reuse this same instance in your OnScrollListener. What you have to do is create a new instance of CaseListingTask every time you want to run it.
So to summarise replace this:
if (mCaseListingTask.getStatus() == AsyncTask.Status.FINISHED) {
currentPage++;
// load more list items:
mCaseListingTask.execute(URL + currentPage);
}
With this:
if (mCaseListingTask.getStatus() == AsyncTask.Status.FINISHED) {
currentPage++;
mCaseListingTask = new CaseListingTask();
mCaseListingTask.execute(URL + currentPage);
}
I'm trying to make a refresh while sliding down on the top of the listview possible. I followed this link to make it work and it does on an activty. But I need it on fragments that are tabbed within a main activity so I cannot as the example shows use this method on my fragments.
Here's the correct code while using an activity:
TestActivity.java
import java.util.ArrayList;
import java.util.List;
import uk.co.senab.actionbarpulltorefresh.library.ActionBarPullToRefresh;
import uk.co.senab.actionbarpulltorefresh.library.PullToRefreshLayout;
import uk.co.senab.actionbarpulltorefresh.library.listeners.OnRefreshListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Fragment;
import android.app.ListFragment;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
public class TestActivity extends BaseActivity {
#Override
protected Fragment getSampleFragment() {
return new SimpleListFragment();
}
public static class SimpleListFragment extends ListFragment implements
OnRefreshListener {
int i = 0;
private PullToRefreshLayout mPullToRefreshLayout;
ArrayAdapter<String> adapter;
List<String> list;
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onViewCreated(view, savedInstanceState);
list = new ArrayList<String>();
int no = 1;
for (int i = 0; i < 5; i++) {
list.add("Item No :" + no++);
}
super.onViewCreated(view, savedInstanceState);
ViewGroup viewGroup = (ViewGroup) view;
// As we're using a ListFragment we create a PullToRefreshLayout
// manually
mPullToRefreshLayout = new PullToRefreshLayout(
viewGroup.getContext());
// We can now setup the PullToRefreshLayout
ActionBarPullToRefresh
.from(getActivity())
// We need to insert the PullToRefreshLayout into the
// Fragment's ViewGroup
.insertLayoutInto(viewGroup)
// Here we mark just the ListView and it's Empty View as
// pullable
.theseChildrenArePullable(android.R.id.list,
android.R.id.empty).listener(this)
.setup(mPullToRefreshLayout);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, list);
// Set the List Adapter to display the sample items
setListAdapter(adapter);
setListShownNoAnimation(true);
}
#Override
public void onRefreshStarted(View view) {
// TODO Auto-generated method stub
// setListShown(false); // This will hide the listview and visible a
// round progress bar
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(5000); // 5 seconds
int itemNo = list.size();
itemNo++;
list.add("New Item No :" + itemNo);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
adapter.notifyDataSetChanged();
// Notify PullToRefreshLayout that the refresh has finished
mPullToRefreshLayout.setRefreshComplete();
// if you set the "setListShown(false)" then you have to
// uncomment the below code segment
// if (getView() != null) {
// // Show the list again
// setListShown(true);
// }
}
}.execute();
}
}
}
I've already tried multiple times to make this method work in my fragment code but I cannot succeed. The code below is a working fragment example without any input of the TestActivity.
InfoFragment.java
import java.util.ArrayList;
import java.util.List;
import com.example.app.Config;
...
import android.app.Activity;
import android.os.Bundle;
import android.provider.Settings.Secure;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
public class TicketInfoFragment extends Fragment {
List<Info> ticketInfo;
TicketFull ticket = new TicketFull();
private DatabaseHelper db;
int ticketId = TicketActivity.getCurrentTicketId();
String androidId;
String authCode;
String platform_url;
int uId;
View rootView;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
db = new DatabaseHelper(getActivity());
androidId = Secure.getString(getActivity().getContentResolver(),
Secure.ANDROID_ID);
Config config = new Config();
config = db.getConfig(androidId);
authCode = config.getAuthCode();
platform_url = config.getPlatformURL();
uId = config.getuId();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_ticket_information, container, false);
fillTicket();
return rootView;
}
private void fillTicket() {
HttpReader httpReader = new HttpReader();
httpReader
.setOnResultReadyListener(new HttpReader.OnResultReadyListener() {
#Override
public void resultReady(String result) {
JsonHelper jsonHelper = new JsonHelper();
ticket = jsonHelper.getTicket(result);
//showTicket();
fillSettings();
}
});
httpReader
.execute("http://aa.domainlink.com:1324/example/API/v1/json.php?auth=example&a=ticket&uauth="
+ authCode + "&uid=" + uId + "&id=" + ticketId);
}
private void readSettings() {
InfoAdapter infoAdapter = new InfoAdapter(
getActivity(), ticketInfo);
final ListView listViewInfo = (ListView) rootView.findViewById(R.id.listViewInfo);
listViewInfo.setAdapter(infoAdapter);
listViewInfo
.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parentView,
View childView, int position, long id) {
}
});
listViewInfo.setEmptyView(rootView.findViewById(R.id.empty));
}
private void fillSettings() {
String dueDate = getString(R.string.noDueDate);
ticketInfo = new ArrayList<Info>();
ticketInfo.add(new Info(getString(R.string.ticket_subject), ticket.getSubject() + ""));
ticketInfo.add(new Info(getString(R.string.ticket_relation), ticket.getRelation() + ""));
ticketInfo.add(new Info(getString(R.string.ticket_status), ticket.getStatus() + ""));
ticketInfo.add(new Info(getString(R.string.ticket_priority), ticket.getPriority() + ""));
ticketInfo.add(new Info(getString(R.string.ticket_created), ticket.getTicketCreate() + ""));
ticketInfo.add(new Info(getString(R.string.ticket_department), ticket.getDepartmentName() + ""));
ticketInfo.add(new Info(getString(R.string.ticket_user), ticket.getUser() + ""));
if (!ticket.getDueDate().equals("00-00-0000 00:00:00")) {
dueDate = ticket.getDueDate();
}
ticketInfo.add(new Info(getString(R.string.ticket_dueDate), dueDate));
readSettings();
}
}
The BaseActivity that the activity normally requires:
BaseActivity.java
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class BaseActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
// Add the Sample Fragment if there is one
Fragment sampleFragment = getSampleFragment();
if (sampleFragment != null) {
getFragmentManager().beginTransaction()
.replace(android.R.id.content, sampleFragment).commit();
}
}
//This method will override by child class. Then base class can get the fragment
protected Fragment getSampleFragment() {
return null;
}
}
Posting my failed tries on implementing the activity method in my fragments would not work I guess so I do not post them.
If anyone of you could help thanks alot.
Android SDK has finally added SwipeRefreshLayout. Maybe you can add this to your layout?
http://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html
I've been working on a personal project in Android and ran into a strange situation regarding an Activity which uses a ListView. The basics of the problem are that I have a list of items, each which have 2 buttons, edit and delete. Right now I'm working on implementing the Delete button, which works functionally, but doesn't update the ListView correctly. Instead, it puts what was just deleted on top of the list. It of course refreshes whenever I renavigate to that activity.
Right now the Delete button is detected inside the a custom BaseAdapter, and when I call the notifyDataSetChanged, the situation described above happens instead of removing the now deleted item. How can I correctly update the list inside the adapter class?
I realize that there have been some questions about this, but I haven't been able to integrate them, and solutions I think may work don't really explain how they work; I'm using this project to understand Android app development more, so I would prefer answers with some level of explanation, although any help is of course appreciated!
Thanks!
Here's the relevent code. Note that this is an unfinished project, so there are some unused/incomplete things inside it. Please ignore these.
EditItemsActivity:
package com.example.mybudget;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
public class EditItemsActivity extends Activity implements OnGestureListener{
private DatabaseHandler db;
private List<DataPoint> dpList;
private EditItemsAdapter adapter;
private ListView lv;
private GestureDetector gestureDetector;
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_items);
// Show the Up button in the action bar.
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
getActionBar().setDisplayHomeAsUpEnabled(true);
db = new DatabaseHandler(this);
dpList = db.allDataThisMonth();
lv = (ListView) findViewById(R.id.edititems);
adapter = new EditItemsAdapter(this, R.id.edititems, dpList);
lv.setAdapter(adapter);
gestureDetector = new GestureDetector(getBaseContext(), this);
// buttonDelete.setVisibility(View.GONE);
}
public void refreshList()
{
adapter.notifyDataSetChanged();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_edit_items, menu);
return true;
}
#Override
public boolean onDown(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
public void onDelete()
{
}
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY)
{
// Log.d("Swipe", "" + velocityX + ", " + velocityY);
// if(velocityX > 200 && velocityY < 50 && velocityY > -50)
// {
// buttonEdit.setVisibility(View.GONE);
// buttonDelete.setVisibility(View.VISIBLE);
// }
// else if(velocityX < -200 && velocityY < 50 && velocityY > -50)
// {
// buttonDelete.setVisibility(View.GONE);
// buttonEdit.setVisibility(View.VISIBLE);
// }
return false;
}
#Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub
}
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
// TODO Auto-generated method stub
return false;
}
#Override
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
}
#Override
public boolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
}
And here's the adapter class:
package com.example.mybudget;
import java.text.NumberFormat;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
public class EditItemsAdapter extends BaseAdapter implements OnClickListener{
private List<DataPoint> dpList;
private Activity activity;
private DatabaseHandler db;
public EditItemsAdapter(Activity a)
{
activity = a;
}
public EditItemsAdapter(Activity a, int textViewResourceId, List<DataPoint> dpList)
{
super();
this.dpList = dpList;
activity = a;
db = new DatabaseHandler(activity);
}
public static class ViewHolder
{
public TextView item1;
public TextView item2;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View v = convertView;
//ViewHolder holder;
NumberFormat format = NumberFormat.getCurrencyInstance();
if (v == null)
{
// LayoutInflater vi =
// (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LayoutInflater vi = activity.getLayoutInflater();
v = vi.inflate(R.layout.edit_grid_items, null);
// holder = new ViewHolder();
// holder.item1 = (TextView) v.findViewById(R.id.edit_item_name);
// holder.item2 = (TextView) v.findViewById(R.id.edit_item_cost);
// v.setTag(holder);
TextView tv1 = (TextView)v.findViewById(R.id.edit_item_name);
TextView tv2 = (TextView)v.findViewById(R.id.edit_item_cost);
Button edit = (Button)v.findViewById(R.id.edit_item_button);
Button delete = (Button)v.findViewById(R.id.delete_item_button);
final DataPoint dp = dpList.get(position);
tv1.setText(dp.getName());
tv2.setText(Float.toString(dp.getCost()));
delete.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
db.deleteRowByKey(dp);
((EditItemsActivity) activity).refreshList();
}
});
}
// else
// holder = (ViewHolder)v.getTag();
// if(dp != null)
// {
// holder.item1.setText(dp.getName());
// holder.item2.setText(format.format(dp.getCost()));
// }
return v;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return dpList.size();
}
#Override
public DataPoint getItem(int position) {
// TODO Auto-generated method stub
return dpList.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return dpList.size();
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
EDIT:
The solution involved the inflation explanation that Adam provided, but required a complete repopulation of dpList, the
dpList = db.allDataThisMonth();
that Anup suggested.
In your getView method of your adapter, you're checking if (convertView == null) and if it's null you're inflating a new view. If it's not null, you're just returning the non-null view that was supplied.
The convertView supplied to the getView method is a cached view that has already been displayed. You're supposed to re-use this (if it's a valid view - you may have multiple different views in your list), rather than inflating a new one. You're forgetting to update the content of it for the corresponding position.
So, how to fix it? Simply close your if (v == null) after inflation:
if (v == null)
{
LayoutInflater vi = activity.getLayoutInflater();
v = vi.inflate(R.layout.edit_grid_items, null);
}
Edit: As Anup points out, you also need to update your dpList variable or it will keep returning the same values for the given position. You can do this in your click listener:
delete.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
db.deleteRowByKey(dp);
dpList.remove((Integer)v.getTag());
((EditItemsActivity) activity).refreshList();
}
});
// Required so we know which index to remove from our dpList.
delete.setTag(position);
From your code, I can see that your adapter is populated by dplist. When you delete a row using db.deleteRowByKey(dp);you are updating the database but you are not updating your dplist.
You need to repopulate your dplist to match the database and only then will notifyDataSetChanged() work as expected.
A simply way to do this would be to change your refreshList() function to:
public void refreshList()
{
//reload dpList so that it can sync up with the database
dpList = db.allDataThisMonth();
//now notify adapter that the data set has changed so that it can update itself.
adapter.notifyDataSetChanged();
}
I am new to android and a little bit confused. i have a listView with image and text. Where, if I click on a Image it should start an activity, and if I click on text another activity.
Cod:
in
onCrete(){
listView = getListView();}
myBaseAdapterItemActivity = new MyBaseAdapterItemActivity(
ItemActivity.this, placeNameList);
setListAdapter(myBaseAdapterItemActivity);
myBaseAdapterItemActivity.notifyDataSetChanged();
listView.setTextFilterEnabled(true);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View view,
int position, long id) {
// One Activity I can start without any problem
// In xml File I set for image clicable to true.
// What I want to do is like this
if(view.getId() == R.id.imageId)
{
Intent intent = new Intent(this, ImageActivity.class);
startActivity(intent);
}
else if(view.getID == R.id.textId)
{
Intent intent = new Intent(this, TextActivity.class);
startActivity(intent);
}
}}
And whenever I click on Image it does not not either in textView.
Any Idea
It has two solutions:
1) Instead on writing onItemClickListener for list you can do findviewbyid the textview and imageview in your custom adapter in getview method and then set onclick listeners on both of them.
2) You can use getChildAt method.... and check which child is your imageview and which is your textview. This is a work around so not much guaranteed.
Try with the below code.
Your adapter should be like below code. then your text and image click will create new activity.
Hi the code should be like below Hope this helps you.
package com.example.listwithclick;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
ListView listView1;
Activity activity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
activity=this;
listView1=(ListView)findViewById(R.id.listView1);
listView1.setAdapter(new MyAddapter(MainActivity.this));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
class MyAddapter extends BaseAdapter {
Context rContext;
private LayoutInflater rInflater;
public MyAddapter(Context c) {
rInflater = LayoutInflater.from(c);
rContext = c;
}
public MyAddapter(Activity imagebinding) {
// TODO Auto-generated constructor stub
activity = imagebinding;
rContext = imagebinding;
rInflater = LayoutInflater.from(imagebinding);
rContext = imagebinding;
rInflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return 10;
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(final int position, View convertView,
ViewGroup parent) {
// TODO Auto-generated method stub
convertView = rInflater.inflate(R.layout.child, null);
final MyDat mydat = new MyDat();
mydat.textview = (TextView) convertView.findViewById(R.id.textView1);
mydat.textview.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(rContext, "text", 1000).show();
Intent image= new Intent(rContext,TextActivity.class);
startActivity(image);
}
});
mydat.imageView1=(ImageView)convertView.findViewById(R.id.imageView1);
mydat.imageView1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(rContext, "image ", 1000).show();
Intent image= new Intent(rContext,ImageActivity.class);
startActivity(image);
}
});
return convertView;
}
class MyDat {
TextView textview;
ImageView imageView1;
}
}
}
In your MyBaseAdapterItemActivity, setOnClickListener((OnCLickListener)mContext) to the ImageVIew and TextView.
In your activity, extends OnClickListener.
write your startActivity(Intent) in the OnClick(View v) depending on v.getId()
In list item xml, for set android:onClick="onFirstLinkClick" and similarly for the image view also,
and the use following method in your activity
public void onFirstLinkClick(View V) {
}
I have created android apps to retrieving Listview using BaseAdapter from ArrayList but not displayed anything in Listview. Description of my apps is that I want retrieve listview using BaseAdapter. when my app is run on emulator nothing is displayed on screen when clicked on menu button on my emulator only add button displayed on screen after clicked on add launch the new activity in that activity i have created two editText. after submit, return to prev activity and display the listview.
Please can anybody help me to find out this error
Following is the Adapter class
package com.oj2.exlistview;
import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView.FindListener;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class TimeTrackAdapter extends BaseAdapter {
ArrayList<TimeRecord> times = new ArrayList<TimeRecord>();
public Context cntxt;
public TimeTrackAdapter(Context cnt,ArrayList<TimeRecord> list2) {
super();
cntxt = cnt;
times = list2;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return new TimeTracker().getList1().size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return getItem(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if (convertView == null){
System.out.println("in getView");
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
convertView = inflater.inflate(R.layout.time_list_item, parent,false);
TimeRecord time = times.get(position);
TextView timeTextView = (TextView) convertView.findViewById(R.id.timeView);
timeTextView.setText(time.getTimes());
TextView noteTextView = (TextView) convertView.findViewById(R.id.noteView);
noteTextView.setText(time.getNotes());
}
return convertView;
}
}
Following is the Activity class
package com.oj2.exlistview;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.ListView;
public class TimeTracker extends Activity{
TimeTrackAdapter timeTrackAdapter;
ListView listView;
TimeRecord timerecord;
public ArrayList<TimeRecord> list1 = new ArrayList<TimeRecord>();
public static final int TIME_ENTRY_REQUEST_CODE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
System.out.println("in onCreate()");
}
public ArrayList<TimeRecord> getList1() {
return list1;
}
public void setList1(ArrayList<TimeRecord> list1) {
this.list1 = list1;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu);
System.out.println("in onCreateOptionsMenu");
MenuInflater mI = getMenuInflater();
mI.inflate(R.menu.time_list_menu,menu);
return true;
}
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
// TODO Auto-generated method stub
System.out.println("in onMenuItemSelected");
if (item.getItemId()==R.id.add_time_menu_item) {
Intent intent = new Intent(this, AddTimeActivity.class);
startActivityForResult(intent, TIME_ENTRY_REQUEST_CODE);
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
System.out.println("in onActivityResult");
if (requestCode==TIME_ENTRY_REQUEST_CODE) {
if (resultCode==RESULT_OK) {
String Time = data.getStringExtra("time");
String Note = data.getStringExtra("note");
list1.add(new TimeRecord(Time, Note));
timeTrackAdapter = new TimeTrackAdapter(this,list1);
listView = (ListView) findViewById(R.id.timeListView);
listView.setAdapter(timeTrackAdapter);
listView.getAdapter();
/* timeTrackAdapter.addTimeRecord(new TimeRecord(Time, Note));*/
timeTrackAdapter.notifyDataSetChanged();
}
}
}
}
Following is the AddTimeActivity
package com.oj2.exlistview;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
public class AddTimeActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.add_time);
}
public void onCancle(View view) {
finish();
}
public void onSave(View view) {
Intent intent = getIntent();
EditText TimeView = (EditText) findViewById(R.id.editText1);
intent.putExtra("time", TimeView.getText().toString());
EditText Noteview = (EditText)findViewById(R.id.editText2);
intent.putExtra("note", Noteview.getText().toString());
this.setResult(RESULT_OK, intent);
finish();
}
}
Thanking You
First, don't create any Activity object in your Adapter. Activity objects are created by Android itself, and they are used to display Views. It has nothing to do with adapters.
The layout you want to display your data in must contain a <ListView ... /> tag, with an android:id="#+id/whatEverId" attribute.
Then what you have to do is to retrieve the ListView object in your TimeTracker activity using its id :
ListView lv = (ListView) findViewById(R.id.whatEverId);
Then create your adapter and tell your ListView that the views you want it to display will be created by your custom adapter :
TimeTrackerAdapter adapter = new TimeTrackerAdapter(this, myListOfData);
lv.setAdapter(adapter);
myListOfData is your ArrayList containing the data. The rest is explicit and should do the job.