如何将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;
}
}
任何帮助都会受到赞赏。感谢
答案 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()
时,我们已经知道view
是null
因此您获得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。 谢谢回复家伙!