Как использовать один и тот же класс Fragment несколько раз в ViewPager и TabLayout? - PullRequest
0 голосов
/ 09 февраля 2020

Итак, я пытаюсь создать несколько вкладок во время выполнения в зависимости от некоторых значений, каждая вкладка содержит фрагмент, а каждый фрагмент содержит несколько диаграмм. проблема в том, что работает только при создании одной вкладки, когда предполагается, что приложение создает sh 2 или более вкладок, поскольку нулевая ссылка на RelativeLayout внутри GraphFragment, этот относительный макет используется для встраивания диаграмма.

здесь xml файлы

Activity_main. xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="2dp"
        android:layout_marginEnd="2dp"
        android:background="@color/white"
        app:tabSelectedTextColor="@color/colorAccent"
        app:tabTextColor="@color/colorPrimary"
        app:tabGravity="center"
        app:tabMode="scrollable"
        app:tabIndicatorHeight="3dp">

    </com.google.android.material.tabs.TabLayout>

    <com.example.cargraph.CustomViewPager
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/viewPager"/>

</androidx.appcompat.widget.LinearLayoutCompat>

фрагмент_графа. xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".GraphFragment"
    android:orientation="vertical">

    <RelativeLayout
        android:id="@+id/graphLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="5dp">

    </RelativeLayout>

</FrameLayout>

это код, который запускает создание вкладок и фрагментов

DataRetriver. java

for(int i=0; i<allData.length(); i++){
    JSONObject stationData = allData.getJSONObject(i);
    JSONObject graphData = stationData.getJSONObject("data");
    ChartBuilder cb = new ChartBuilder(
           graphData.getJSONObject("date_time"),
           graphData.getJSONObject("values"),
           "label",
           activity, //this is a reference to main activity
           stationsList.get(i)
    );
    cb.createChart();
}

ChartBuilder. java

public class ChartBuilder {

    private JSONObject xValues;
    private JSONObject yValues;
    private String label;
    private LineChart lineChart;
    private MainActivity mActivity;
    private String tabLabel;

    public ChartBuilder(JSONObject xValues, JSONObject yValues, String label,
                        MainActivity mActivity, String tabLabel) {
        this.xValues = xValues;
        this.yValues = yValues;
        this.label = label;
        this.lineChart = new LineChart(mActivity);
        this.mActivity = mActivity;
        this.tabLabel = tabLabel;
    }

    private void createTab(){
        GraphFragment graphFragment = new GraphFragment();
        mActivity.addGraphFragment(graphFragment, tabLabel);
        RelativeLayout graphLayout = graphFragment.getGraphLayout(); //this is the nullPointerException when allData.length() > 2 in DataRetriver.java
        graphLayout.addView(lineChart);
    }

    private LineDataSet createDataSet() throws JSONException {
        List<Entry> entries = new ArrayList<Entry>();
        JSONArray names = xValues.names();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        long timeReference = 0;
        long newXvalue;
        for(int i=0; i<names.length(); i++){
            try{
                if(i==0){
                    Date date = simpleDateFormat.parse(xValues.getString(names.getString(i)));
                    timeReference = date.getTime();
                }
                Date date = simpleDateFormat.parse(xValues.getString(names.getString(i)));
                Timestamp timestamp = new Timestamp(date.getTime());
                newXvalue = timestamp.getTime()- timeReference;
                entries.add(new Entry(newXvalue, yValues.getLong(names.getString(i))));
            }catch (ParseException p){
                System.out.println(p.toString());
            }
        }
        LineDataSet lineDataSet = new LineDataSet(entries, this.label);
        lineDataSet.setColor(R.color.colorPrimary);
        lineDataSet.setValueTextColor(R.color.colorAccent);
        return lineDataSet;
    }

    public void createChart() throws JSONException {
        LineData lineData = new LineData(createDataSet());
        this.lineChart.setData(lineData);
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                RelativeLayout.LayoutParams.MATCH_PARENT,
                RelativeLayout.LayoutParams.MATCH_PARENT
        );
        this.lineChart.setLayoutParams(layoutParams);
        this.lineChart.invalidate();
        createTab();
    }
}

GraphFragment. java

public class GraphFragment extends Fragment {

    private RelativeLayout graphLayout;


    public GraphFragment() {

    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_graph, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        graphLayout = getView().findViewById(R.id.graphLayout);
    }

    public RelativeLayout getGraphLayout() {
        return graphLayout;
    }
}

MainActivity. java

public class MainActivity extends AppCompatActivity {

    private TabLayout tabLayout;
    private CustomViewPager viewPager;
    private ViewPagerAdapter viewPagerAdapter;

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

        setupView();

        setupViewPagerAdapter(new HomeFragment());
    }

    private void setupView(){

        tabLayout = findViewById(R.id.tabLayout);
        viewPager = findViewById(R.id.viewPager);
        viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());

    }


    private void setupViewPagerAdapter(Fragment fragment){
        viewPagerAdapter.addFragment(fragment, "Inicio");
        viewPager.setAdapter(viewPagerAdapter);
        viewPager.setPagingEnabled(false);

        tabLayout.setupWithViewPager(viewPager, true);

    }

    public void addGraphFragment(Fragment fragment, String title){
        viewPagerAdapter.addFragment(fragment, title);
        viewPagerAdapter.notifyDataSetChanged();
    }

    public void removeGraphFragment(){
        viewPagerAdapter.removeFragments();
        viewPagerAdapter.notifyDataSetChanged();
    }

    public ViewPagerAdapter getViewPagerAdapter() {
        return viewPagerAdapter;
    }
}

Не понимаю, почему с 1 вкладкой она работает просто отлично, но 2 или более появляется NullPointerException, есть идеи? Спасибо!

...