我正在尝试根据其余调用返回的输入更新View
,它代表graph(MpAndroidChart=library, class=BarChart)
,位于Fragment
内。我尝试使用名为updateGraph()
的方法更新View,并且我得到一个空指针异常
我的updateGraph()
方法的代码如下。
对此的任何帮助将不胜感激。
有关如何调用此方法的一般说明如下:我的MainActivity
创建了一个runnable,它在我创建并用作字段的updateGraph()
实例上调用FragmentOne
在我的Activity
然后我将该runnable传递给我的RestCall(AsyncTask)
,以避免传递活动本身
当返回来自其余调用的信息时,我将其保存为单例并引用它,类似于您在SharedPreferences
中的操作,以更新图形。
下面的代码使用预定义的值来更新图表,并且不用担心引用刚刚描述的信息,因为我只是想在此时更新图表。
public class FragmentOne extends Fragment implements Summary {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.fragment_one, container, false);
return view;
}
@Override
public void updateGraph() {
BarChart theChart = (BarChart) this.getView().findViewById(R.id.chart_frag_one);
ArrayList<BarEntry> entries = new ArrayList<>();
List<TupleFloat> prices = new ArrayList<TupleFloat>();
prices.add(new TupleFloat(2,4));
prices.add(new TupleFloat(3,4));
prices.add(new TupleFloat(1,6));
prices.add(new TupleFloat(3,1));
prices.add(new TupleFloat(1,1));
prices.add(new TupleFloat(7,2));
prices.add(new TupleFloat(3,2));
int prices_length = prices.size(); // need to delete
for (int i = 1; i < prices_length+1; i++){
entries.add(new BarEntry( (float) (i*2), new float[] {prices.get(i-1).getX(), prices.get(i-1).getY()}));
}
BarDataSet dataset = new BarDataSet(entries, " Summary"); // asbtract Summary
String datas[] = {"regular", "peak"};
dataset.setStackLabels(datas);
dataset.setColors(new int[] {R.color.portal_dark_blue, R.color.portal_light_blue}, getActivity());
YAxis left = theChart.getAxisLeft();
left.setAxisMaxValue(10);//dataset.getYMax()+2);
left.setAxisMinValue(0);
theChart.getAxisRight().setEnabled(false);
XAxis bottomAxis = theChart.getXAxis();
bottomAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
bottomAxis.setValueFormatter(new AxisValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
// return values will all be the values of the dates array
int value_i = (int) value;
Log.d("hello", Integer.toString(value_i));
switch(value_i){
case 2:
return "Jul 27";
case 4:
return "Jul 28";
case 6:
return "Jul 29";
case 8:
return "Jul 30";
case 10:
return "Jul 31";
case 12:
return "Aug 1";
case 14:
return "Aug 2";
}
return "";
}
@Override
public int getDecimalDigits() {
return 0;
}
});
bottomAxis.setAxisMinValue(0);
bottomAxis.setLabelCount(16); // size of array * 2 + 1
bottomAxis.setAxisMaxValue(dataset.getXMax()+3); // going to be dates-array based
bottomAxis.setDrawGridLines(false);
theChart.setDrawValueAboveBar(false);
theChart.setDescription("");
BarData data = new BarData(dataset);
theChart.setData(data);
// legend
Legend legend = theChart.getLegend();
legend.setYOffset(40);
legend.setPosition(Legend.LegendPosition.BELOW_CHART_CENTER);
legend.setTextSize(200);
}
}
堆栈追踪:
08-09 12:59:27.312 27094-27094/com.example.schadtj.portalapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.schadtj.portalapp, PID: 27094
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
at com.example.schadtj.portalapp.FragmentOne.updateGraph(FragmentOne.java:38)
at com.example.schadtj.portalapp.MainActivity$1.run(MainActivity.java:36)
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)
Fragment_one xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/fvone"
>
<LinearLayout
android:id="@+id/tobegraph"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.mikephil.charting.charts.BarChart
android:id="@+id/chart_frag_one"
style="@style/AppTheme"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android" />
</LinearLayout>
</LinearLayout>
MainActivity必备代码
public class MainActivity extends Activity{
FragmentManager FM = getFragmentManager();
private BottomBar mBottomBar;
FragmentOne frag1;
@Override
public void onCreate(Bundle savedInstanceState) {
// Map of Runnables
Map<String, Runnable> rest_runnables = new HashMap<String, Runnable>();
frag1 = new FragmentOne();
Runnable summary = new Runnable() {
@Override
public void run() {
frag1.updateGraph();
}
};
rest_runnables.put("Summary", summary);
new RestUpdateAll(this, ((MyApplication) this.getApplication()).returnUser(), rest_runnables).execute();
答案 0 :(得分:0)
这显然意味着在片段视图被夸大之前已经调用了updateGraph
。
一个简单的解决方案是在updateGraph中添加一个简单的检查,如:
if (getView() != null){
/* your code */
}
相反,您可以在MainActivity中添加一个检查。例如:
Fragment frg = (Fragment)getFragmentManager().findFragmentById(R.id.your_fragment);
if (frg != null){
/* call updateGraph */
}
答案 1 :(得分:0)
请勿在此活动中致电updateGraph
(请参阅您的run
方法)。 Fragment在那时没有View,因此getView
将返回null,如错误中所示。
FragmentOne f = new FragmentOne();
f.updateGraph(); // This is bad... Will throw error
// fragment transaction ...
相反,您可以在加载片段时更新片段的图形。你的&#34; runnable&#34;如果您希望定期刷新此视图,则应以某种方式附加到Fragment。
public class FragmentOne extends Fragment implements Summary {
private BarChart theChart;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.fragment_one, container, false);
theChart = (BarChart) view.findViewById(R.id.chart_frag_one);
// Any other findViewById...
return view;
}
@Override
public void updateGraph() {
ArrayList<BarEntry> entries = new ArrayList<>();
List<TupleFloat> prices = new ArrayList<TupleFloat>();
prices.add(new TupleFloat(2,4));
...