0

Hi all I have a bit of a weird problem with my app I am populating a list in a RecyclerView using an Async Task. Everything works OK but when there is no data to populate I want to inflate another layout to show an error message.

public class generateAds extends AsyncTask<String, Void, Void> {

    protected Void doInBackground(String... params)
    {
        //Filling the list -This part is OK
    }         
    //Here is my problem  
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        spinner.setVisibility(View.GONE);
        if(ads.size() > 0)
        {
            if (isFirstSearch)
            {
                isFirstSearch = false;                    
                cardAdapter = new CardAdapter(context, ads);                   
                recyclerViewZone.setAdapter(cardAdapter);                   
                recyclerViewZone.setItemAnimator(new DefaultItemAnimator());
            }
            else
            {
                for (int i = 0; i < ads.size(); i++) {
                    cardAdapter.add(ads.get(i), cardAdapter.getItemCount());
                }
            }
            generatedAdsFromScroll = false;
        }
        else
        {
            //This doesn't inflate 
            try
            {
                rootView = inflater.inflate(R.layout.error_internet_connection,container,false);
            }catch (Exception e)
            {
                e.printStackTrace(); //No exception thrown for some reason
            }

        }
    }
}

So in my onPostExecute After I check if the list ADS contains something it should go and inflate my layout. The weird thing is that it does read it, but no layout is shown on the screen it doesnt throw any exceptions of any sort. What could be the problem?

user3182266
  • 1,270
  • 4
  • 23
  • 49
  • Could you show the entire Activity code ? Specifically what you do with rootView. – 2Dee Jan 15 '15 at 13:02
  • rootView is declared as a view: View rootView; no need for the whole code – user3182266 Jan 15 '15 at 13:03
  • What is rootView? What you need to do is hide your ListView/RecyclerView if it is empty and then inflate the layout of your choice in it's place. Once inflated you still need to add that view somewhere – RED_ Jan 15 '15 at 13:04
  • I just cant understand why its not inflating its reading it (I have debugged it) but nothing is shown on the screen. And there is no exception – user3182266 Jan 15 '15 at 13:05
  • If I add recyclerViewZone.setVisibility(View.GONE); before I inflate it again nothing is shown :/ – user3182266 Jan 15 '15 at 13:07
  • 1
    See my edit. inflating it is fine, but where is it going? For example if I wanted it to be the be header of my recyclerView I would go recyclerView.addHeaderView(rootView); then it would show up. It needs to be set somewhere. – RED_ Jan 15 '15 at 13:08
  • possible duplicate of [Unable to inflate a layout on button click](http://stackoverflow.com/questions/27901244/unable-to-inflate-a-layout-on-button-click) – 2Dee Jan 15 '15 at 13:23

3 Answers3

1

You are only inflating the view , but not adding the view to any viewgroup. Try addView(View v) to add a view.

Navdroid
  • 1,541
  • 3
  • 25
  • 52
0

Although it is only a guess because you don't show your entire code, I think you never set rootView as the content of your Activity.

Instead of this

try {
    rootView = inflater.inflate(R.layout.error_internet_connection,container,false);
}catch (Exception e) {
    e.printStackTrace(); //No exception thrown for some reason
}

do this

setContentView(R.layout.error_internet_connection);

Alternatively, you could declare the View you want to show when there is no connection inside the main layout, have it hidden by default and call setVisibility(View.VISIBLE) on that View and setVisibility(View.GONE) on the rest of the layout when no connection is available.

EDIT : after seeing your edit about the class not being part of an Activity, your code should not compile. To have this work properly, the best method is probably to leave the Activity handle its Views.

Things you need to do :

  • Change your AsyncTask from AsyncTask<String, Void, Void> to AsyncTask<String, Void, ReturnObject> where ReturnObject is the data produced by the AsyncTask. Change the onPostExecute(Void aVoid) to onPostExecute(ReturnObject returnObject) as well.

  • Declare an interface ReturnDataHandler in your AsyncTask, having one handleData(ReturnObject returnObject) method, and have your Activity implement it. Declare one instance as member variable of the AsyncTask (mDataHandler) and take one instance as constructor argument. Pass your Activity when starting the AsyncTask. That way, in onPostExecute, you simply do mDataHandler.handleData(returnObject), and it is the method handleData(returnObject) that will handle the Views based on the result of the AsyncTask...

2Dee
  • 8,609
  • 7
  • 42
  • 53
  • Opas you are right I forgot to mention this is not an activity this is a class – user3182266 Jan 15 '15 at 13:08
  • If your edit is complete, recyclerViewZone.setAdapter should not even compile because recyclerViewZone is not declared anywhere. Are you sure you are showing the complete code ? – 2Dee Jan 15 '15 at 13:10
  • ... That is an interesting theory but do i say that everything else is working as it should? – user3182266 Jan 15 '15 at 13:11
0

When changing Adapter's data, in this case, CardAdapters data, you need to call its notifyDataSetChanged() method to allow all views that are bound to this adapter to update and redraw itself. Documentation from developer.android.com :

public void notifyDataSetChanged()

Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.

nstosic
  • 2,584
  • 1
  • 17
  • 21