I have a ListView that each item in the list contains multiple images.
When I create the list, I want to async download the image so the list can show fast and the images can fill in when they are downloaded.
I have extended the AsyncTask class and implemented a simple download method. However, I am not sure how to update the image back to the correct position in the list view in:
#Override
protected void onPostExecute(Bitmap result) {
// TODO show the downloaded image to the list
super.onPostExecute(result);
}
Here's my class definition:
public class ImageDownloadWorker extends AsyncTask<String, Void, Bitmap>
And my doInBackground method:
#Override
protected Bitmap doInBackground(String... params) {
try {
return downloadBitmap(params[0]);
} catch (ClientProtocolException e) {
return null;
} catch (Exception e) {
return null;
}
}
What is the common pattern we should use to map the downloaded image to the correct ImageView of the correct list item in the list? Thank you!
You need to implement an adapter pattern to populate the listview. In your case, you can create a custom adapter class and extend BaseAdapter and implement all its methods. The pattern goes like this.
MainActivity.java
public class MainActivity extends Activity {
private ListView listView;
private CustomAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
listView = findViewById(android.R.id.list);
}
private class ImageDownloader extends AsyncTask<String, Void, Bitmap> {
#Override
protected Bitmap doInBackground(String... strings) {
try {
return downloadBitmap(params[0]);
} catch (ClientProtocolException e) {
return null;
} catch (Exception e) {
return null;
}
}
#Override
protected void onPostExecute(Bitmap bitmap) {
adapter = new CustomAdapter(bitmap);
listView.setAdapter(adapter);
super.onPostExecute(bitmap);
}
}
private class CustomAdapter extends BaseAdapter {
private Bitmap bitmap;
private LayoutInflater inflater = null;
class ViewHolder {
ImageView image;
}
public CustomAdapter(Bitmap bitmap) {
this.bitmap = bitmap;
inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return 0;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView == null) {
convertView = inflater.inflate(R.layout.list_item, parent, false);
holder.image = convertView.findViewById(R.id.imageView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.image.setImageBitmap();
return convertView;
}
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
list_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
However, when you are loading many images into the listview, create an ArrayList and send that to the listAdapter
I need to do the same of you in lot of projects and this library is very very helpful and very simple to use:
https://github.com/koush/UrlImageViewHelper
Related
no image is shown from URL even if i tried one image in onCreate it actually works with the same URL but with the RecyclerView nothing is shown
my On Create Method
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NetworkUtilites ob=new NetworkUtilites();
ob.execute();
/** moviesArray contains Movies with Description **/
moviesArray=ob.getArrayMovies();
adapter = new RecyclerViewAdapter( this, moviesArray);
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setAdapter(adapter);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
}
Here is onBindViewHolder function
public void onBindViewHolder(#NonNull ViewHolder holder, final int position) {
/** MoviesArray return description of movie , getPoster_path() path return URL Of the poster film**/
String moviePosterURL= moviesArray.get(position).getPoster_path();
if(!TextUtils.isEmpty(moviePosterURL))
{
Picasso.get().load(moviePosterURL).into(holder.imageView);
}
}
Here is onCreateViewHolder function
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layoul_listitem,parent,false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
Here is ViewHolder function
public class ViewHolder extends RecyclerView.ViewHolder
{
ImageView imageView;
RelativeLayout parentlayout;
public ViewHolder(#NonNull View itemView)
{
super(itemView);
imageView=itemView.findViewById(R.id.image);
parentlayout =itemView.findViewById(R.id.parent_layout);
}
}
layout_listitem.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/parent_layout"
>
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:id="#+id/image"
/>
</RelativeLayout>
activity_main.xml with the Recycler View
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
NetworkUtilites class
public class NetworkUtilites extends AsyncTask<Void,Void,Void>
{
private static final String MoviesURL="http://api.themoviedb.org/3/movie/popular?api_key=";
private ArrayList <ListItem> arrayMovies =new ArrayList<>();
private String sent=null;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... strings)
{
try
{
URL url = new URL(MoviesURL);
HttpURLConnection urlConnection=(HttpURLConnection)url.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
sent=StreamtoString(in);
in.close();
}
catch (Exception e)
{
}
return null;
}
#Override
protected void onPostExecute(Void s)
{
super.onPostExecute(s);
}
public String StreamtoString(InputStream inputStream)
{
BufferedReader bureader= new BufferedReader(new InputStreamReader(inputStream));
String line;
String Text = "";
try{
while((line=bureader.readLine())!=null)
{
Text+=line;
}
} catch (Exception e) {
}
return Text;
}
public String getSent() {
return sent;
}
public ArrayList<ListItem> getArrayMovies()
{
try {
JSONObject parentObject;
JSONArray parentArray;
if (!sent.equals(null))
{
parentObject = new JSONObject(sent);
parentArray = parentObject.getJSONArray("results");
System.out.println(parentArray.length());
for (int i = 0; i < parentArray.length(); i++)
{
JSONObject movieDetails = parentArray.getJSONObject(i);
String poster_path="http://image.tmdb.org/t/p/w342";
poster_path += movieDetails.getString("poster_path");
String original_title=movieDetails.getString("original_title");
String overview= movieDetails.getString("overview");
int vote_average=movieDetails.getInt("vote_average");
String release_date=movieDetails.getString("release_date");
ListItem ob= new ListItem(original_title,poster_path,overview,vote_average,release_date);
arrayMovies.add(ob);
}
}
}
catch (Exception e)
{
}
return arrayMovies;
}
}
This question already has answers here:
getLayoutInflater() in fragment
(5 answers)
Closed 4 years ago.
I'm trying to code an app that downloads data of some events from an online MySQL database and writes it into my android app. Right now, what i'm trying to do is just testing if downloading the name of the event works, but i keep getting this error:
java.lang.NoSuchMethodError: No virtual method getLayoutInflater()Landroid/view/LayoutInflater; in class Lcom/suspicio/appfisio_business/FrammentoCorsi; or its super classes (declaration of 'com.suspicio.appfisio_business.FrammentoCorsi' appears in /data/app/com.suspicio.appfisio_business-1/split_lib_slice_8_apk.apk)
at com.suspicio.appfisio_business.FrammentoCorsi$EventoAdapter.getView(FrammentoCorsi.java:204)
which points to the line:
listViewItem = getLayoutInflater().inflate(R.layout.frammento_corsi, null, true);
Here's my code (it's a fragment):
FrammentoCorsi.java:
public class FrammentoCorsi extends Fragment {
public static final int CODE_GET_REQUEST = 1024;
public static final int CODE_POST_REQUEST = 1025;
public FrammentoCorsi() { //Vuoto
}
boolean isUpdating = false;
View rootView;
List<Evento> eventoList;
ListView listView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.frammento_corsi, container, false);
listView = (ListView) rootView.findViewById(R.id.listViewEventi);
return rootView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
eventoList = new ArrayList<>();
readEventi();
}
private void readEventi() {
PerformNetworkRequest request = new PerformNetworkRequest(Api.URL_READ_EVENTI, null, CODE_GET_REQUEST);
request.execute();
}
private void refreshEventoList(JSONArray eventi) throws JSONException {
//clearing previous heroes
eventoList.clear();
//traversing through all the items in the json array
//the json we got from the response
for (int i = 0; i < eventi.length(); i++) {
//getting each hero object
JSONObject obj = eventi.getJSONObject(i);
//adding the hero to the list
eventoList.add(new Evento(
obj.getInt("id"),
obj.getString("titolo"),
obj.getString("inizio"),
obj.getString("fine"),
obj.getInt("categoria"),
obj.getString("link"),
obj.getString("luogo")
));
}
//creating the adapter and setting it to the listview
EventoAdapter adapter = new EventoAdapter(eventoList);
listView.setAdapter(adapter);
}
//inner class to perform network request extending an AsyncTask
public class PerformNetworkRequest extends AsyncTask<Void, Void, String> {
//the url where we need to send the request
String url;
//the parameters
HashMap<String, String> params;
//the request code to define whether it is a GET or POST
int requestCode;
ProgressBar barra = (ProgressBar) getView().findViewById(R.id.progressBar);
//constructor to initialize values
PerformNetworkRequest(String url, HashMap<String, String> params, int requestCode) {
this.url = url;
this.params = params;
this.requestCode = requestCode;
}
//when the task started displaying a progressbar
#Override
protected void onPreExecute() {
super.onPreExecute();
barra.setVisibility(View.VISIBLE);
}
//this method will give the response from the request
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
barra.setVisibility(View.INVISIBLE);
try {
JSONObject object = new JSONObject(s);
if (!object.getBoolean("error")) {
Toast.makeText(getActivity().getApplicationContext(), object.getString("message"), Toast.LENGTH_SHORT).show();
refreshEventoList(object.getJSONArray("eventi"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
//the network operation will be performed in background
#Override
protected String doInBackground(Void... voids) {
RequestHandler requestHandler = new RequestHandler();
if (requestCode == CODE_POST_REQUEST)
return requestHandler.sendPostRequest(url, params);
if (requestCode == CODE_GET_REQUEST)
return requestHandler.sendGetRequest(url);
return null;
}
}
class EventoAdapter extends ArrayAdapter<Evento> {
List<Evento> eventoList;
//constructor to get the list
public EventoAdapter(List<Evento> eventoList) {
super(getActivity(), R.layout.frammento_corsi, eventoList);
this.eventoList = eventoList;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View listViewItem = convertView;
if (listViewItem == null) {
listViewItem = getLayoutInflater().inflate(R.layout.frammento_corsi, null, true);
}
//getting the textview for displaying name
TextView textViewName = listViewItem.findViewById(R.id.nomeeventocalendario);
//the update and delete textview
//ImageView textViewUpdate = listViewItem.findViewById(R.id.notifica);
//ImageView textViewDelete = listViewItem.findViewById(R.id.link);
final Evento evento = eventoList.get(position);
textViewName.setText(evento.getTitolo());
return listViewItem;
}
}
}
And its resource file frammento_corsi.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.suspicio.appfisio_business.FrammentoCorsi">
<ListView
android:id="#+id/listViewEventi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/nomeeventocalendario"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="gone"/>
</FrameLayout>
Can you help me out?
Thanks in advance!
Use this
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
listViewItem = layoutInflater.inflate(R.layout.frammento_corsi, null ,true);
Instead of this
listViewItem = getLayoutInflater().inflate(R.layout.frammento_corsi, null, true);
I am attempting to use the Swipecards library (https://github.com/Diolor/Swipecards) to build a tinder-esqe application. I am using a BaseAdapter to populate a layout with two text views and an image view that will be provided to the main SwipeFlingAdapterView. While both of the text fields are populated, I cannot get the image to appear on the cards. I have tried this implementation with both an ArrayAdapter and a BaseAdapter and the results are the same.
The activity layout (deal_page_layout)
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent">
<com.lorentzos.flingswipe.SwipeFlingAdapterView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/swipe_fling_view"
app:rotation_degrees="10"
tools:context=".DealPage"
android:alpha="1.0"
app:max_visible="2"
app:min_adapter_stack="5"/>
</FrameLayout>
The layout being populated by the BaseAdapter (deal_card)
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="#+id/deal_card_image">
</ImageView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/deal_card_title"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_margin="15dp"
android:gravity="center"
android:textSize="20dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/deal_card_description"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_margin="15dp"
android:gravity="center"
android:textSize="20dp"/>
</RelativeLayout>
BaseAdapter class
public class DealBaseAdapter extends BaseAdapter {
private Context context;
private List<GrubbyDeal> dealList;
private LayoutInflater li;
public DealBaseAdapter(Context context, LayoutInflater li, ArrayList<GrubbyDeal> dealList){
this.context = context;
this.dealList = dealList;
this.li = li;
}
#Override
public int getCount(){
return dealList.size();
}
#Override
public Object getItem(int position){
return dealList.get(position);
}
#Override
public long getItemId(int position){
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder viewHolder;
//resuse a view if possible
if(convertView == null){
convertView = li.inflate(R.layout.deal_card,parent,false);
viewHolder = new ViewHolder();
viewHolder.img = (ImageView) convertView.findViewById(R.id.deal_card_image);
viewHolder.title = (TextView) convertView.findViewById(R.id.deal_card_title);
viewHolder.desc = (TextView) convertView.findViewById(R.id.deal_card_description);
convertView.setTag(viewHolder);
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
GrubbyDeal curDeal = dealList.get(position);
viewHolder.img.setImageURI(curDeal.getImageUri());
viewHolder.title.setText(curDeal.getTitle());
viewHolder.desc.setText(curDeal.getDescription());
return convertView;
}
//view holder class to hold cached findViewByID results
private static class ViewHolder {
public ImageView img;
public TextView title;
public TextView desc;
}
And the main activity (DealPage)
public class DealPage extends Activity {
private ArrayList<GrubbyDeal> dealList;
private DealBaseAdapter dealAdapter;
SwipeFlingAdapterView flingContainer;
#Override
public void onCreate(Bundle sis){
super.onCreate(sis);
setContentView(R.layout.deal_page_layout);
//add some awesome cat deals to the adapter
dealList = new ArrayList<>();
for(int i=0; i < 5; i++){
GrubbyDeal tmp = new GrubbyDeal(i);
dealList.add(tmp);
}
//add another type of cat deal to the list
dealList.add(new GrubbyDeal());
dealAdapter = new DealBaseAdapter(this, getLayoutInflater(), dealList);
flingContainer = (SwipeFlingAdapterView) findViewById(R.id.swipe_fling_view);
flingContainer.setAdapter(dealAdapter);
flingContainer.setFlingListener(new SwipeFlingAdapterView.onFlingListener() {
#Override
public void removeFirstObjectInAdapter() {
// this is the simplest way to delete an object from the Adapter (/AdapterView)
Log.d("LIST", "removed object!");
GrubbyDeal popped = dealList.remove(0);
dealList.add(popped);
dealAdapter.notifyDataSetChanged();
}
#Override
public void onLeftCardExit(Object dataObject) {
makeToast(DealPage.this, "Left!");
}
#Override
public void onRightCardExit(Object dataObject) {
makeToast(DealPage.this, "Right!");
}
#Override
public void onAdapterAboutToEmpty(int itemsInAdapter) {
dealList.add(new GrubbyDeal());
dealAdapter.notifyDataSetChanged();
Log.d("LIST", "notified");
}
#Override
public void onScroll(float scrollProgressPercent) {
View view = flingContainer.getSelectedView();
}
});
flingContainer.setOnItemClickListener(new SwipeFlingAdapterView.OnItemClickListener() {
#Override
public void onItemClicked(int itemPosition, Object dataObject) {
makeToast(DealPage.this, "Clicked!");
}
});
}
}
Am I missing something obvious? Is there some vastly superior library that I should be using? Thanks,
Ian
I would recommend using Picasso to load images into your imageview.
Picasso.with(context).load(imgurl).into(viewHolder.img);
The problem was formatting. I was attempting to use
Uri.parse("android.resource://com.thepackage.theapp/R.drawable.cat4.jpg");
but wasn't getting a valid Uri back. So instead I am using resource ids with picasso and the card works great!
I need to add dot indicator to my code for slide show so kindly help me to add this indicator and also click listner for views in page viewer
viewPager = (ViewPager) findViewById(R.id.splash);
ImageAdapter adapter = new ImageAdapter(this);
viewPager.setAdapter(adapter);
public class ImageAdapter extends PagerAdapter {
Context context;
private int[] GalImages = new int[] {
R.drawable.slider,
R.drawable.slider,
R.drawable.slider,
};
ImageAdapter(Context context){
this.context=context;
}
#Override
public int getCount() {
return GalImages.length;
// return 10;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((ImageView) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView imageView = new ImageView(context);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setImageResource(GalImages[position]);
new LoadImage(imageView).execute("http://www.gadgetbaazar.com/wp-content/uploads/2016/12/Top-Mobile-Phones.jpg");
new LoadImage(imageView).execute("https://pisces.bbystatic.com/BestBuy_US/store/ee/2015/com/pm/nav_desktops_1115.jpg");
container.addView(imageView, 0);
return imageView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((ImageView) object);
}
private class LoadImage extends AsyncTask<String, String, Bitmap> {
ImageView img=null;
public LoadImage(ImageView img){
this.img=img;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
protected Bitmap doInBackground(String... args) {
Bitmap bitmap=null;
try {
bitmap = BitmapFactory.decodeStream((InputStream)new URL(args[0]).getContent());
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
protected void onPostExecute(Bitmap image) {
if(image != null){
img.setImageBitmap(image);
}
}
}
}
Here i need the indicators if possible along with pageclick listner for this viewpager
I done this using following LIB PageIndicatorView
compile 'com.romandanylyk:pageindicatorview:0.1.1'
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:id="#+id/pager"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
<com.rd.PageIndicatorView
android:id="#+id/pageIndicatorView"
android:layout_width="wrap_content"
android:layout_centerHorizontal="true"
android:layout_above="#+id/buttons"
android:layout_marginBottom="20dp"
app:piv_animationType="swap"
app:piv_viewPager="#id/pager"
android:layout_height="wrap_content" />
Java code
mViewPager = (ViewPager) findViewById(pager);
mViewPager.setAdapter(mCustomPagerAdapter);
//dots
PageIndicatorView pageIndicatorView = (PageIndicatorView) findViewById(R.id.pageIndicatorView);
pageIndicatorView.setViewPager(mViewPager);
OUTPUT
Im currently doing some android developer that lists items in a ListView, we have created a WebView that add's a JavaScript interface to our page and our page sends information via the JavaScript interface. this all works as expected, so we set up a class called HangoutManager that extends a BaseAdapter, we have implemented several methods in there such as add/remove and exists.
This all works fine and now were at the point where need to use the BaseAdapter to update the ViewList when there changes to the Array Stack.
We can't seem to get it too work, the getView() function never get's called to generate an item. here is some code.
onCreate
public void onCreate(Bundle savedInstanceState)
{
//Call parent to construct the Activity
super.onCreate(savedInstanceState);
//Create Instance of HangoutManager, must be called here
HangoutManagerList = HangoutManager.Instance(this);
//Set the content view to the main ListView
setContentView(R.layout.main);
//instantiate the WebView
CanopyWebView = new CanopyWebView(this);
setListAdapter(HangoutManagerList);
}
HangoutManager
public class HangoutManager extends BaseAdapter
{
public static HangoutManager _Instance;
private ArrayList<JSONObject> DataSet = new ArrayList<JSONObject>();
protected LayoutInflater Inflater;
public static HangoutManager Instance(Context context)
{
if(_Instance == null)
{
_Instance = new HangoutManager(context);
Log.v("HangoutManager", "Instance Created");
}
return _Instance;
}
public HangoutManager(Context context)
{
this.Inflater = LayoutInflater.from(context);
}
public boolean remove(String id)
{
try
{
for(int i=0 ; i< DataSet.size() ; i++ )
{
if(DataSet.get(i).getString("id").equals(id))
{
DataSet.remove(i);
Log.v("HangoutManager", "hangout Removed");
return true;
}
}
}
catch (JSONException e)
{
Log.e("HangoutManager::exists",e.getMessage());
return false;
}
return false;
}
public boolean add(String hangout)
{
try
{
JSONObject HangoutJson = new JSONObject(hangout);
if(this.exists(HangoutJson.getString("id")))
{
this.remove(HangoutJson.getString("id"));
}
DataSet.add(HangoutJson);
Log.v("HangoutManager", "hangout Added");
notifyDataSetChanged();
}
catch(JSONException e)
{
Log.e("HangoutManager",e.getMessage());
}
return true;
}
public boolean exists(String id)
{
try
{
for(int i=0 ; i< DataSet.size() ; i++ )
{
if(DataSet.get(i).getString("id").equals(id))
{
Log.v("HangoutManager", "hangoutExists: " + id);
return true;
}
}
}
catch (JSONException e)
{
Log.e("HangoutManager::exists",e.getMessage());
return false;
}
return false;
}
#Override
public int getCount()
{
return DataSet.size();
}
#Override
public Object getItem(int position)
{
return DataSet.get(position);
}
#Override
public long getItemId(int position)
{
return position;
}
#Override
public View getView(int position, View view, ViewGroup viewGroup)
{
if(view == null)
{
view = Inflater.inflate(R.layout.item1, viewGroup, false);
}
//Get the JSONObject for the Item
JSONObject entity = DataSet.get(position);
//Set the JSONObject as the tag for the row
view.setTag(entity);
//return the view to be drawn
return view;
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#00000000"
android:id="#android:id/list">
</ListView>
item1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
<TextView
android:id="#+id/text"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:background="#FFFFFFFF"
android:gravity="center_vertical"
android:text="#string/app_name"
android:textColor="#FF000000"
android:visibility="visible" />
</LinearLayout>
StackTrace (not error stacktrace)
http://pastebin.com/1ftkiLBF
The section about is where we attempt to break but it never breaks at that point, am we doing something wrong ?
Update
The application seems to crash sometime during the notifyDataSetChanged() calls.
You shouldn't call the inflater like this.
Use the following syntax to get an Inflater to use from your getView()
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Also about the stacktrace, it looks like your JS interface callbacks are executed in background. You cannot modify the data collection binded to the ListView nor call updateNotifyDataset() from a background thread.
But you can ask the UIThread to do it for you by calling your add method like this:
yourActivityInstance.runOnUiThread(new Runnable() {
public void run() {
yourAdapterInstance.add(newHangout);
}});