2015-09-10 1 views
0

Я создаю listview, который загружает элементы из parse.com в пользовательский адаптер. Приложение отлично работает на устройствах api ниже 19. Тем не менее, с ошибкой на logcat в api 19 и выше, он абсолютно не работает. Я застрял в этом вопросе уже два дня. Вот мой код:Listview не заполняется новыми версиями Android

package com.edwardokoth.turnapp.fragments; 

import android.app.Activity; 
import android.app.ProgressDialog; 
import android.content.Context; 
import android.os.Bundle; 
import android.support.v4.widget.SwipeRefreshLayout; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.Button; 
import android.widget.ImageView; 
import android.widget.ListView; 
import android.widget.ProgressBar; 
import android.widget.TextView; 

import com.edwardokoth.turnapp.R; 
import com.edwardokoth.turnapp.adapters.HomepageAdapter; 
import com.edwardokoth.turnapp.utils.Helper; 
import com.edwardokoth.turnapp.utils.ParseConstants; 
import com.parse.FindCallback; 
import com.parse.ParseException; 
import com.parse.ParseFile; 
import com.parse.ParseImageView; 
import com.parse.ParseObject; 
import com.parse.ParseQuery; 
import com.parse.ParseRelation; 

import java.util.List; 

public class WhatsHotFragment extends android.support.v4.app.ListFragment { 
    public static String[] objectIds; 
    public static ParseFile[] images; 
    private Callbacks activity; 
    private ProgressBar whatsHotProgressBar; 
    protected SwipeRefreshLayout mSwipeRefreshLayout; 
    int initialLimit = 10, newLimit = initialLimit, mListviewCount; 
    private boolean hasFooterButton; 

    public WhatsHotFragment() { 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.fragment_whats_hot, 
       container, false); // sets the xml to be used in this fragment. 


     return rootView; 
    } 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     whatsHotProgressBar = (ProgressBar) getActivity().findViewById(R.id.whatsHotProgressBar); 
     whatsHotProgressBar.setVisibility(View.VISIBLE); 
    } 


    public interface Callbacks { 
     void onItemSelected(ParseFile image, String objectId); 
    } 

    @Override 
    public void onListItemClick(ListView l, View v, int position, long id) { 
     ParseFile image = images[position]; 
     String objectId = objectIds[position]; 
     super.onListItemClick(l, v, position, id); 
     activity.onItemSelected(image, objectId); 
    } 

    @Override 
    public void onAttach(Activity activity) { 
     super.onAttach(activity); 
     this.activity = (Callbacks) activity; 
    } 
    @Override 
    public void onResume() { 
     super.onResume(); 
     if(Helper.isNetworkAvailable(getActivity())) { 
      retrieveEventList(newLimit); 
     }else { 
      Helper.makeToast(getActivity(), "Network is unavailable"); 
     } 

     Button btnLoadMore = new Button(getActivity()); 
     btnLoadMore.setText("Load More"); 



     if(!hasFooterButton) { 
      getListView().addFooterView(btnLoadMore); 
      hasFooterButton = true; 

      btnLoadMore.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        if(Helper.isNetworkAvailable(getActivity())) { 
         ProgressDialog pDialog = new ProgressDialog(
           getActivity()); 
         whatsHotProgressBar.setVisibility(View.VISIBLE); 
         newLimit += 4; 
         mListviewCount = getListView().getCount() - 3; 
         retrieveEventList(newLimit); 
        }else { 
         Helper.makeToast(getActivity(), "Network is unavailable"); 
        } 
       } 
      }); 
     } 

    } 


    protected SwipeRefreshLayout.OnRefreshListener mOnRefreshListener = new SwipeRefreshLayout.OnRefreshListener() { 
     @Override 
     public void onRefresh() { 
      retrieveEventList(initialLimit); 
     } 
    }; 


    private void retrieveEventList(int limit) { 
     ParseQuery<ParseObject> myQuery = ParseQuery.getQuery("Events"); 
     myQuery.addDescendingOrder("rsvp"); 
     myQuery.addDescendingOrder("createdAt"); 
     myQuery.setLimit(limit); 
     myQuery.findInBackground(new FindCallback<ParseObject>() { 
      @Override 
      public void done(List<ParseObject> eventObjects, ParseException e) { 
       whatsHotProgressBar.setVisibility(View.INVISIBLE); 
       if(mSwipeRefreshLayout.isRefreshing()){ 
        mSwipeRefreshLayout.setRefreshing(false); 
       } 
       if (e == null) { 
        String[] eventNames = new String[eventObjects.size()]; 
        images = new ParseFile[eventObjects.size()]; 
        objectIds = new String[eventObjects.size()]; 

        int i = 0; 
        for (ParseObject user : eventObjects) { 
         eventNames[i] = eventObjects.get(i).getString("eventName"); 
         images[i] = user.getParseFile("bannerImage"); 
         objectIds[i] = user.getObjectId(); 
         i++; 
        } 
        HomepageAdapter homepageAdapter = new HomepageAdapter(getActivity(), 
          R.layout.party_fragment, eventNames, images); 
        setListAdapter(homepageAdapter); 
//     setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, test)); 
        if(getListView().getAdapter() == null) { 

        }else { 
//      getListView().smoothScrollToPosition(mListviewCount); 
         getListView().setSelection(mListviewCount); 
        } 

        if(eventObjects.isEmpty()){ 
         Helper.showEmptyTextView("No items to display", getListView()); 
        } 
       } else { 
        Helper.showEmptyTextView("No items to display", getListView()); 
       } 
      } 
     }); 
    } 
} 

Это класс адаптера. Как вы можете видеть из комментариев, аварий приложений Whithin этого класса

package com.edwardokoth.turnapp.adapters; 



import android.content.Context; 
import android.graphics.Bitmap; 
import android.net.Uri; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.ImageView; 
import android.widget.TextView; 

import com.edwardokoth.turnapp.R; 
import com.parse.ParseFile; 
import com.parse.ParseImageView; 
import com.squareup.picasso.Picasso; 

/** 
* Created by Arnold on 8/27/2015. 
*/ 
public class HomepageAdapter extends ArrayAdapter<String> { 

    protected Context context; 
    String[] strings; 
    ParseFile[] images; 
    Uri fileUri; 



    public HomepageAdapter(Context context, int resource, String[] objects, 
        ParseFile[] images) { 
     super(context, resource, objects); 
     this.context = context; 
     this.strings = objects; 
     this.images = images; 


    } 

    @Override 
    public int getCount() { 
     return strings.length; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     LayoutInflater inflater = LayoutInflater.from(context); 
     View row = inflater.inflate(R.layout.party_fragment, parent, false); 

     ParseImageView iv = (ParseImageView)row.findViewById(R.id.eventPic); //After lots of debugging, I found out that the app crashes around this point 
     TextView tv = (TextView) row.findViewById(R.id.event_name_tv_home); 

     tv.setText(strings[position]); 


     fileUri = Uri.parse(images[position].getUrl()); 

     Picasso.with(context).load(fileUri).fit().into(iv); 


     return row; 
    } 
} 

Это файл XML, содержащий ListView:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/my_events_at_profile" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#00ffffff" 
    android:orientation="vertical"> 

    <TextView 
     android:id="@android:id/empty" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="" /> 

    <android.support.v4.widget.SwipeRefreshLayout 
     android:id="@+id/swipeRefreshLayout" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"> 

     <ListView 
      android:id="@android:id/list" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:divider="@null" 
      android:dividerHeight="0dp"/> 
    </android.support.v4.widget.SwipeRefreshLayout> 

    <ProgressBar 
     android:id="@+id/whatsHotProgressBar" 
     style="?android:attr/progressBarStyleLarge" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerHorizontal="true" 
     android:layout_centerVertical="true" 
     android:indeterminate="false" /> 


</RelativeLayout> 

И это файл используется для настройки ListView

<?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:background="#eee" 
    android:orientation="vertical" > 

     <RelativeLayout 
      android:id="@+id/image_and_button" 
      android:layout_width="match_parent" 
      android:layout_height="200dp" 
      android:orientation="vertical" 
      android:layout_weight="25" 
      android:weightSum="100" 
      android:padding="5dp" 
      android:elevation="20dp" 
      > 

      <com.parse.ParseImageView 
       android:id="@+id/eventPic" 
       android:layout_width="match_parent" 
       android:layout_height="200dp" 
       android:scaleType="centerCrop" 
       android:src="@drawable/ic_child"/> 

      <TextView 
       android:id="@+id/event_name_tv_home" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:text="Ravin&apos; pool party" 
       android:textColor="#fff" 
       android:shadowColor="#000" 
       android:shadowDx="10" 
       android:shadowRadius="30" 
       android:textSize="30sp" 
       android:textStyle="bold" 
       android:layout_alignBottom="@+id/eventPic" 
       android:layout_alignParentLeft="true" 
       android:layout_alignParentStart="true" /> 


     </RelativeLayout> 
    <View 
     android:layout_width="fill_parent" 
     android:layout_height="5dip" 
     android:background="@drawable/drop_shadow" 
     /> 

</LinearLayout> 
+0

«Это, однако, сбой абсолютно без ошибок на логарифме» - это невозможно, должна произойти сбой в стеке, если ваше приложение выйдет из строя. – agamov

+0

@agamov Я думаю, что это глупая ошибка в Android Studio (по крайней мере для меня), что logcat не показывает никаких ошибок, даже если приложение выходит из строя. Это может быть ошибка ACRA, хотя, поскольку я использую это, а также для загрузки журналов сбоев. Я прибегал к проверке следа исключений на выходе, который загружает ACRA. Что касается вопроса, 'ListView' должен работать на всех версиях. Попытайтесь выяснить, где он падает, поставив точки останова, если вы не можете получить выход kogcat. – kha

+0

Я проделал много отладки, и я обнаружил, что приложение вылетает из класса адаптера где-то после: View row = inflater.inflate (R.layout.party_fragment, parent, false); –

ответ

0

Существует новая улучшенная версия/вид ListView. Его RecyclerView. Попробуйте использовать RecyclerView. Если вы новичок в этом виджетах, пожалуйста, прочитайте достаточно и перед тем, как положить руку на свой код. Example

+0

Я следил за учебником и добавил ресайклинг. Точно такой же результат! Работает как шарм на устройствах и эмуляторах ниже api 19, но падает без объяснения причин api 19 и выше. –

0

Попробуйте удалить следующие строки из RelativeLayout в свой макет изделия.

android:layout_weight="25" 
android:weightSum="100" 
android:elevation="20dp" 

Атрибут android:elevation был добавлен в API21. Это может вызвать проблему. И первые два атрибута выглядят ненужными.

Если вы хотите поднять View, вы должны использовать CardView в качестве контейнера. И обязательно прочитайте документацию CardView, потому что она не ведет себя последовательно на всех платформах.

И выезд ViewHolder pattern для ListView s. Это улучшит производительность, если у вас большой список.

+0

Я изменил код, чтобы использовать ViewHolder, и после сотен операторов журнала я понял, что переменная position в getView() перерабатывается в более новых версиях, в то время как она просто увеличивается в более старых версиях. например. если число элементов равно шестью, в более старых версиях переменная позиции равна 0,1,2,3,4,5, а в более новых версиях она перерабатывается до 0,1,2,3,0,1. Есть ли способ решить эту проблему? –

+0

Вы уверены, что не кешируете переменную позиции в своем ViewHolder? –

0

Исправлено! Это странно, но вся проблема была устранена просто путем изменения радиуса тени в моем текстовом представлении с 30 до 20. Спасибо за помощь.