2015-01-03 2 views
0

Так что я делаю приложение, которое тянет историю с сервера. История прибывает, разбивается на части. Я хочу поместить каждую часть истории на другую страницу ViewPager, но то, что я пробовал до сих пор, либо приводит к сбою приложения, либо просто дает мне пустой экран.Viewpager с данными из asynctask

Это мой код для этой деятельности:

package com.firegaming.myfirstapp; 

import android.app.ProgressDialog; 
import android.os.AsyncTask; 
import android.os.Parcelable; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.FragmentStatePagerAdapter; 
import android.support.v4.view.ViewPager; 
import android.support.v7.app.ActionBarActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 

import org.apache.http.NameValuePair; 
import org.apache.http.message.BasicNameValuePair; 
import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 


public class ContinueStoryActivity extends FragmentActivity { 


private ProgressDialog pDialog; 
JSONParser jsonParser = new JSONParser(); 
private static int partCounter; 
private static String storyID; 
ArrayList<String> storyPartList = new ArrayList<>(); 
FragmentStatePagerAdapter adapter; 
ViewPager pager; 
JSONArray parts = null; 

private static final String GET_STORY_URL = "http://firegaming.host56.com/get_story.php"; 
private static final String TAG_SUCCESS = "success"; 
private static final String TAG_MESSAGE = "message"; 
private static final String TAG_PARTS = "parts"; 
private static final String TAG_PARTCOUNT = "partCount"; 
private static final String TAG_STORYID = "storyID"; 
private static final String TAG_STORYTEXT = "storyText"; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_continue_story); 


    pager = (ViewPager) findViewById(R.id.pager); 
    adapter = new MyPagerAdapter(getSupportFragmentManager()); 
    pager.setAdapter(adapter); 

    new GetStory().execute(); 

} 


@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.menu_continue_story, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 

    //noinspection SimplifiableIfStatement 
    if (id == R.id.action_settings) { 
     return true; 
    } 

    return super.onOptionsItemSelected(item); 
} 

public class MyPagerAdapter extends FragmentStatePagerAdapter { 

    public MyPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int pos) { 
     return StoryFragment.newInstance(storyPartList.get(pos).toString()); 
    } 

    @Override 
    public int getCount() { 
     return storyPartList.size(); 
    } 

    public int getItemPosition(Object object){ 
     return POSITION_NONE; 
    } 

    @Override 
    public void restoreState(Parcelable arg0, ClassLoader arg1) { 
     //do nothing here! no call to super.restoreState(arg0, arg1); 
    } 
} 



    class GetStory extends AsyncTask<String, String, String>{ 

    @Override 
    protected void onPreExecute(){ 
     super.onPreExecute(); 
     pDialog = new ProgressDialog(ContinueStoryActivity.this); 
     pDialog.setMessage("Getting Story..."); 
     pDialog.setIndeterminate(false); 
     pDialog.setCancelable(true); 
     pDialog.show(); 
    } 

    @Override 
    protected String doInBackground(String... args){ 
     int success; 
     try{ 

      List<NameValuePair> params = new ArrayList<NameValuePair>(); 
      params.add(new BasicNameValuePair("username", MainActivity.USERNAME)); 

      Log.d("Request!", "Starting!"); 

      JSONObject json = jsonParser.makeHttpRequest(GET_STORY_URL, "GET", params); 

      Log.d("Story Attempt", json.toString()); 
      success = json.getInt(TAG_SUCCESS); 
      if (success == 1){ 

       parts = json.getJSONArray(TAG_PARTS); 
       partCounter = Integer.parseInt(json.getString(TAG_PARTCOUNT)); 
       storyID = json.getString(TAG_STORYID); 
       return json.getString(TAG_SUCCESS); 

      } else { 

       Log.d("Story Get Failure!", json.getString(TAG_MESSAGE)); 
       return json.getString(TAG_MESSAGE); 
      } 

     } catch (JSONException ex){ 
      ex.printStackTrace(); 
     } 

     return null; 
    } 

    @Override 
    protected void onPostExecute(String file_url) { 

     pDialog.dismiss(); 

     if (file_url != null) { 
      try { 
       for (int i = 0; i < parts.length(); i++) { 
        JSONObject c = parts.getJSONObject(i); 
        int id = c.getInt(TAG_STORYID); 
        String storyText = c.getString(TAG_STORYTEXT); 
        storyPartList.add(id-1, storyText); 
       } 
      } catch (JSONException ex) { 
       ex.printStackTrace(); 
      } 

      adapter.notifyDataSetChanged(); 

     } 

    } 

} 


} 

Что я здесь делаю неправильно?

EDIT: Когда не возвращается нуль, как было предложено, приложение снова сработает. Это все ошибки, возникающие в logcat при сбое приложения.

01-03 12:29:19.298 29861-29861/com.firegaming.myfirstapp E/AndroidRuntime﹕ FATAL EXCEPTION: main 
Process: com.firegaming.myfirstapp, PID: 29861 
java.lang.NullPointerException 
     at com.firegaming.myfirstapp.ContinueStoryActivity$MyPagerAdapter.getItem(ContinueStoryActivity.java:88) 
     at android.support.v4.app.FragmentStatePagerAdapter.instantiateItem(FragmentStatePagerAdapter.java:105) 
     at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:837) 
     at android.support.v4.view.ViewPager.populate(ViewPager.java:987) 
     at android.support.v4.view.ViewPager.populate(ViewPager.java:919) 
     at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:447) 
     at com.firegaming.myfirstapp.ContinueStoryActivity$GetStory.onPostExecute(ContinueStoryActivity.java:163) 
     at com.firegaming.myfirstapp.ContinueStoryActivity$GetStory.onPostExecute(ContinueStoryActivity.java:99) 
     at android.os.AsyncTask.finish(AsyncTask.java:632) 
     at android.os.AsyncTask.access$600(AsyncTask.java:177) 
     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645) 
     at android.os.Handler.dispatchMessage(Handler.java:102) 
     at android.os.Looper.loop(Looper.java:136) 
     at android.app.ActivityThread.main(ActivityThread.java:5586) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:515) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084) 
     at dalvik.system.NativeStart.main(Native Method) 
+0

сообщение LogCat ошибка –

+1

Потому что 'если (успех == 1)' 'вы вернуть null' так что вы ничего не видите :-) – mmlooloo

+0

да, ты не возвращая ничего после вашего успеха. –

ответ

1

У меня есть список предложений:

я отношусь с подозрением на то, что storyPartList является hasmap с идентификаторами продиктовал быть поступающие данные. Если входящий идентификатор, например, равен [0,2,3], то getItem (1) завершится с ошибкой. Что произойдет, если вы позволите storyPartLists просто быть arraylist (поскольку название типа предполагает, что это так)?

getCount адаптера аналогично диктуется поступающих данных:

@Override 
public int getCount() { 
    return partCounter; 
} 

Вместо того, чтобы позволить счетчика зависит от фактического размера storyPartList:

@Override 
public int getCount() { 
    return storyPartList.size(); 
} 

Теперь, имея данные пейджера определяется чисто по объему данных, добавленных в storyPartList, я бы предложил создать пейджер один раз в onCreate() вместо того, чтобы его воссоздавать каждый раз, когда вы добавляете историю:

ViewPager pager; 
FragmentStatePagerAdapter adapter; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_continue_story); 
    new GetStory().execute(); 

    pager = (ViewPager) findViewById(R.id.pager); 
    adapter = new MyPagerAdapter(getSupportFragmentManager()) 
    pager.setAdapter(adapter); 
} 

И в onPostExecute теперь просто сделать:

adapter.notifyDataSetChanged(); 

Это заставит адаптер обновить его содержимое на основе содержания storyPartList. Для того, чтобы правильно сделать обновление адаптера, возможно, придется добавить это к MyPagerAdapter:

public int getItemPosition(Object object){ 
    return POSITION_NONE; 
} 

Резюме предложений

  • Сделать storyPartList быть список вместо карты
  • Пусть GetCount вернуться storyPartList.size()
  • Создать пейджер в onCreate и вызвать notifyDataSetChanged при добавлении истории
  • Fina LLY реализовать getItemPosition в адаптере, чтобы сделать его обновить правильно
+0

Я внедрил все ваши предложения (мой пост отредактирован, чтобы отразить их в коде), и, хотя теперь он больше не разбивается, он по-прежнему отображает только пустой белый экран. – Fireprufe15

+0

Хорошо, это действительно работает, я просто делал глупые вещи позже. Код, как сейчас, является функциональным благодаря изменениям, которые вы предложили. Спасибо! – Fireprufe15

+0

Cool np :) happy coding – cYrixmorten

0

Предполагая, что все хорошо с веб-сервиса, и вы правильно анализировать данные, добавьте следующий код в ваш MyPagerAdapter класс:

@Override 
public void restoreState(Parcelable arg0, ClassLoader arg1) { 
     //do nothing here! no call to super.restoreState(arg0, arg1); 
} 

Сначала попробуйте это и посмотреть, если он работает. .. также, пожалуйста, напишите лог-код вашего сбоя.

еще три вещи, которые вы должны обеспечить:

  1. Убедитесь, что android.support.v4.app.Fragment и android.app.Fragment классы не используются вместе. Используйте все только из библиотеки поддержки v4.

  2. Убедитесь, что getCount() возвращает фактическое число фрагментов, соответствующих вашему методу getItem(int index): использовать storyPartList.size() в getCount().

  3. Как cYrixmorten предложил, сделать storyPartListArrayList и вызвать storyPartList.add(...) вместо storyPartList.put(...).

+0

Я добавил это, но, похоже, это не имеет большого значения. Я знаю, что все в порядке на стороне веб-службы, поскольку я отслеживал код и мог видеть верные значения, возвращаемые туда. – Fireprufe15

+0

'android.support.v4.app.Fragment' используется везде, а' android.app.Fragment' нигде. Просто об этом подумал. 'getCount()' получает значение из значений, выведенных из Интернета и всегда должен соответствовать количеству частей сюжета и, следовательно, сколько фрагментов должно появиться. – Fireprufe15

+0

ok cool ... мы сужаем количество возможных ошибок ... теперь PLS видит переизданный пост. –

Смежные вопросы