将JSON ArrayList填充到Spinner中

时间:2016-04-01 22:58:43

标签: android json arraylist

如何将projectList的ArrayList中的对象放入Spinner。这是我的代码

public class MainPage extends AppCompatActivity implements AsyncResponse {
private ArrayList<ProjectNames> projectsList;
private Spinner spinner1;
final String LOG = "MainPage";


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main_page);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);


    PostResponseAsyncTask taskRead = new PostResponseAsyncTask(MainPage.this, this);
    taskRead.execute("http://10.0.2.2/Client/ProjectRead.php");


}

@Override
public void processFinish(String s) {
    projectsList = new JsonConverter<ProjectNames>().toArrayList(s, ProjectNames.class);
    //Log.d(LOG, "processFinish: " + s);
    BindDictionary<ProjectNames> dict = new BindDictionary<ProjectNames>();

    dict.addStringField(R.id.tvProjectName, new StringExtractor<ProjectNames>() {

        @Override
        public String getStringValue(ProjectNames projects, int position) {
            return projects.projectname;
        }
    });

    FunDapter<ProjectNames> adaptor = new FunDapter<>(MainPage.this, projectsList, R.layout.support_simple_spinner_dropdown_item, dict);
    spinner1 = (Spinner) findViewById(R.id.spFirstChoice);
    spinner1.setAdapter(adaptor);
}

}`

当我运行我的代码时,它只是崩溃了。 注意:我创建了一个自定义xml文件,我在其中创建了tvProjectNames,用于存储ProjectName类中的对象。 ProjectName.class:

package com.example.anthony.project2016;

import com.google.gson.annotations.SerializedName;

public class ProjectNames {

@SerializedName("id")
public int id;
@SerializedName("projectname")
public String projectname;
}

我在processFinish中得到的是:

 processFinish: [{"id":"1","projectname":"project1"},{"id":"2","projectname":"project2"},{"id":"3","projectname":"project3"},{"id":"4","projectname":"project4"},{"id":"5","projectname":""},{"id":"6","projectname":"Project5"}]`

这是应用崩溃后的错误:

04-01 22:55:31.478 2350-2350/com.example.anthony.project2016 E/AndroidRuntime: FATAL EXCEPTION: main
                                                                           Process: com.example.anthony.project2016, PID: 2350
                                                                           java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setVisibility(int)' on a null object reference
                                                                               at com.amigold.fundapter.FunDapterUtils.handleStringFields(FunDapterUtils.java:231)
                                                                               at com.amigold.fundapter.FunDapterUtils.showData(FunDapterUtils.java:84)
                                                                               at com.amigold.fundapter.FunDapter.showData(FunDapter.java:123)
                                                                               at com.amigold.fundapter.FunDapter.getView(FunDapter.java:107)
                                                                               at android.widget.AbsSpinner.onMeasure(AbsSpinner.java:194)
                                                                               at android.widget.Spinner.onMeasure(Spinner.java:580)
                                                                               at android.support.v7.widget.AppCompatSpinner.onMeasure(AppCompatSpinner.java:410)
                                                                               at android.view.View.measure(View.java:18788)
                                                                               at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
                                                                               at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
                                                                               at android.view.View.measure(View.java:18788)
                                                                               at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
                                                                               at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:607)
                                                                               at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onMeasureChild(AppBarLayout.java:1238)
                                                                               at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:672)
                                                                               at android.view.View.measure(View.java:18788)
                                                                               at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
                                                                               at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
                                                                               at android.support.v7.internal.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:124)
                                                                               at android.view.View.measure(View.java:18788)
                                                                               at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
                                                                               at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
                                                                               at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
                                                                               at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
                                                                               at android.view.View.measure(View.java:18788)
                                                                               at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
                                                                               at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
                                                                               at android.view.View.measure(View.java:18788)
                                                                               at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
                                                                               at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
                                                                               at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
                                                                               at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
                                                                               at android.view.View.measure(View.java:18788)
                                                                               at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
                                                                               at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
                                                                               at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2643)
                                                                               at android.view.View.measure(View.java:18788)
                                                                               at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2100)
                                                                               at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1216)
                                                                               at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1452)
                                                                               at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
                                                                               at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
                                                                               at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
                                                                               at android.view.Choreographer.doCallbacks(Choreographer.java:670)
                                                                               at android.view.Choreographer.doFrame(Choreographer.java:606)
                                                                               at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
                                                                               at android.os.Handler.handleCallback(Handler.java:739)
                                                                               at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                               at android.os.Looper.loop(Looper.java:148)
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                               at java.lang.reflect.Method.invoke(Native Method)
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

FunDaptor.java:

/**
* A generic adapter that takes a BindDictionary and data and shows them.    Does
* basic validation for you for all fields and also handles the ViewHolder
* pattern.
*
* @param <T>
* @author Ami G
*/
public class FunDapter<T> extends BaseAdapter implements Filterable {

protected ArrayList<T> mDataItems;
protected ArrayList<T> mOrigDataItems;
protected final Context mContext;
private final int mLayoutResource;
private final BindDictionary<T> mBindDictionary;
private int oddColorRes;
private int evenColorRes;
private FunDapterFilter<T> funDapterFilter;
private Filter mFilter;

/**
 * A generic adapter that takes a BindDictionary and data and shows them.
 * Does basic validation for you for all fields and also handles the
 * ViewHolder pattern.
 *
 * @param context
 * @param dataItems      - An arraylist of model items
 * @param layoutResource - resource ID of a layout to inflate for each item. (Example:
 *                       R.layout.list_item)
 * @param dictionary     - The dictionary that will match between fields and data.
 */
public FunDapter(Context context, ArrayList<T> dataItems, int layoutResource,
                 BindDictionary<T> dictionary) {
    this.mContext = context;
    this.mDataItems = dataItems;
    this.mOrigDataItems = dataItems;
    this.mLayoutResource = layoutResource;
    this.mBindDictionary = dictionary;
}

/**
 * Replace the current dataset with a new one and refresh the views. This
 * will call notifyDataSetChanged() for you.
 *
 * @param dataItems
 */
public void updateData(ArrayList<T> dataItems) {
    this.mDataItems = dataItems;
    this.mOrigDataItems = dataItems;
    notifyDataSetChanged();
}

@Override
public int getCount() {
    if (mDataItems == null || mBindDictionary == null) return 0;

    return mDataItems.size();
}

@Override
public T getItem(int position) {
    return mDataItems.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

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

    // Inflate a new view or use a recycled view.
    View v = convertView;
    GenericViewHolder holder;
    if (null == v) {
        LayoutInflater vi =
                (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(mLayoutResource, null);
        holder = new GenericViewHolder();
        holder.root = v;

        // init the sub views and put them in a holder instance
        FunDapterUtils.initViews(v, holder, mBindDictionary);

        v.setTag(holder);
    } else {
        holder = (GenericViewHolder) v.getTag();
    }

    // Show the data
    final T item = getItem(position);
    showData(item, holder, position);

    return v;
}

private void showData(T item, GenericViewHolder holder, int position) {

    // handles alternating background colors if selected
    if (oddColorRes > 0 && evenColorRes > 0) {
        if (position % 2 == 0) {
            holder.root.setBackgroundColor(mContext.getResources().getColor(evenColorRes));
        } else {
            holder.root.setBackgroundColor(mContext.getResources().getColor(oddColorRes));
        }
    }

    FunDapterUtils.showData(item, holder, position, mBindDictionary);
}

public FunDapter<T> setAlternatingBackground(int oddColorRes, int evenColorRes) {

    if (oddColorRes <= 0 || evenColorRes <= 0) {
        throw new IllegalArgumentException("Color parameters are illegal");
    }

    this.oddColorRes = oddColorRes;
    this.evenColorRes = evenColorRes;

    return this;
}

@Override
public Filter getFilter() {
    return mFilter;
}

/**
 * Use this method to enable filtering in the adapter.
 *
 * @param filter - a filter implementation for your adapter.
 */
public void initFilter(FunDapterFilter<T> filter) {

    if (filter == null)
        throw new IllegalArgumentException("Cannot pass a null filter to FunDapter");

    this.funDapterFilter = filter;

    mFilter = new Filter() {

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {

            @SuppressWarnings("unchecked") ArrayList<T> list = (ArrayList<T>) results.values;

            if (results.count == 0) {
                resetData();
            } else {
                mDataItems = list;
            }

            notifyDataSetChanged();
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            FilterResults results = new FilterResults();
            if (constraint == null || constraint.length() == 0) {

                // No constraint - no point in filtering.
                results.values = mOrigDataItems;
                results.count = mOrigDataItems.size();
            } else {
                // Perform the filtering operation

                ArrayList<T> filter =
                        funDapterFilter.filter(constraint.toString(), mOrigDataItems);

                results.count = filter.size();
                results.values = filter;

            }

            return results;
        }
    };
}

public void resetData() {
    mDataItems = mOrigDataItems;
}

}

任何帮助都会受到赞赏。感谢

2 个答案:

答案 0 :(得分:0)

Logcat向我指出FunDaptorUtils

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setVisibility(int)' on a null object reference
     at com.amigold.fundapter.FunDapterUtils.handleStringFields(FunDapterUtils.java:231)

FunDaptorUtils内,你可以看到该库有错误的逻辑:

// fill data
if (!TextUtils.isEmpty(stringValue) && view != null) {
     view.setText(stringValue);
     view.setVisibility(View.VISIBLE);
} else {
     view.setVisibility(field.visibilityIfNull);
}

这是错误的,因为当view == null else块尝试访问view.setVisibility()时,我们已经知道viewnull因此您获得NullPointerException 1}} ...
将代码切换为:

if (view != null) {
     if (!TextUtils.isEmpty(stringValue)) {
          view.setText(stringValue);
          view.setVisibility(View.VISIBLE);
     } else {
          view.setVisibility(field.visibilityIfNull);
     }
}

然而真正的问题是:为什么这个TextView为空?这可能是因为id

中的support_simple_spinner_dropdown_item.xml错误

答案 1 :(得分:0)

    @Override
public void processFinish(String s) {
    projectsList = new JsonConverter<ProjectNames>().toArrayList(s, ProjectNames.class);
    Log.d(LOG, "processFinish: " + s);
    BindDictionary<ProjectNames> dict = new BindDictionary<ProjectNames>();

    dict.addStringField(R.id.tvProjectName, new StringExtractor<ProjectNames>() {

        @Override
        public String getStringValue(ProjectNames projects, int position) {
            return projects.projectname;
        }
    });

    FunDapter<ProjectNames> adaptor = new FunDapter<>(MainPage.this, projectsList, R.layout.spinner, dict);
    spinner1 = (Spinner) findViewById(R.id.spFirstChoice);
    spinner1.setAdapter(adaptor);
}

}

我放下了错误的xml文件。我调用了我的xml文件spinner而不是support_simple_spinner_dropdown_item。 谢谢回复家伙!