[Android] findViewById aanroepen vanuit AsyncTask in Fragmen

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Marco1994
  • Registratie: Juli 2012
  • Nu online
Ik ben bezig om een Android app te maken. Wat ik wil doen is vanuit een rest api wat gegevens ophalen en deze in de GUI te laten zien. Echter omdat het over een wat grotere applicatie gaat en ik dingen schaalbaar/modulair wil maken, heb ik gekozen om de boel dmv fragment lichtelijk uit elkaar te trekken.

Wanneer ik in een AsyncTask dmv onPostExecute findViewById aanroep krijg ik Null exceptioneel terug. Uit mijn onderzoek blijkt dat dit komt omdat de activity nog niet gecreëerd is. Echter roep ik deze aan vanuit onActivityCreated (onViewCreated ook al geprobeerd) waar volgens deze website blijkt dat de activity wel zou moeten bestaan. Nu ben ik ten einde raad en zou ik niet weten waar ik verder naar zou moeten kijken.

CategoryFragment
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
public class CategoryFragment extends Fragment {
    private ArrayList<Category> categories;
    private HttpCategoryRequest httpCategoryRequest;
    private Category selectedCategory;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.categories = new ArrayList<>();

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_category, parent, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        this.httpCategoryRequest = new HttpCategoryRequest(this);
        this.httpCategoryRequest.execute();

        this.addListeners();
    }

    private void addListeners(){
        GridView gridviewCategories = (GridView) getView().findViewById(R.id.gridviewCategories);

        gridviewCategories.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                selectedCategory = getCategoryFromId(position);
                Toast.makeText(getActivity(),
                        "Selected category: " + selectedCategory.getName(), Toast.LENGTH_LONG).show();
                //gridviewProducts.setAdapter(new ImageAdapterProducts(self, selectedCategory.getProducts()));
            }
        });
    }

    private Category getCategoryFromId(int id){
        return this.categories.get(id);
    }

    private class HttpCategoryRequest extends AsyncTask<Void, Void, LinkedList<Category>> {
        private Fragment categoryFragment;

        public HttpCategoryRequest(Fragment fragment){
            this.categoryFragment = categoryFragment;
        }

        @Override
        protected LinkedList<Category> doInBackground(Void... params) {
            try {
                final String url = "http://10.0.2.2:8080/category/getAll";
                RestTemplate restTemplate = new RestTemplate();
                restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
                Category[] categoryObjects = restTemplate.getForObject(url, Category[].class);
                LinkedList<Category> categories = new LinkedList<>(Arrays.asList(categoryObjects));
                return categories;
            } catch (Exception e) {
                e.printStackTrace();
            }

            return null;
        }

        @Override
        protected void onPostExecute(LinkedList<Category> categories) {
            ArrayList<Category> a_categories = null;
            if(a_categories == null) {
                a_categories = new ArrayList<>();
            }

            for(Category category : categories) {
                a_categories.add(category);
            }

            GridView gridviewCategories = getActivity().findViewById(R.id.gridviewCategories);
            gridviewCategories.setAdapter(new ImageAdapterCategories(categoryFragment.getActivity(), a_categories));
        }
    }
}


Wanneer ik findViewById aanroep vanuit mijn MainActivity werkt het wel. Het ligt dus niet aan een verkeerd id oid.

Alle reacties


Acties:
  • 0 Henk 'm!

  • Teknix1982
  • Registratie: Januari 2005
  • Niet online
Kun je geen public property aanmaken van het view element dat je wilt gaan gebruiken in de fragment en die vanuit de OnPostExecute aanroepen?

Acties:
  • 0 Henk 'm!

  • Marco1994
  • Registratie: Juli 2012
  • Nu online
Teknix1982 schreef op donderdag 5 april 2018 @ 13:50:
Kun je geen public property aanmaken van het view element dat je wilt gaan gebruiken in de fragment en die vanuit de OnPostExecute aanroepen?
Wanneer ik in mijn fragment de betreffende GridView opvraag vanuit de onPostExecute is deze nog steeds null.

Acties:
  • 0 Henk 'm!

  • GianniDPC
  • Registratie: Juli 2011
  • Laatst online: 05-10 01:19
Heb je je code als eens gedebugd? Kun je zien wat er precies wanneer opgeroepen wordt en kun je zo misschien je fout wel terugvinden.

Acties:
  • 0 Henk 'm!

  • Marco1994
  • Registratie: Juli 2012
  • Nu online
Ik heb het nu werkend door in mijn MainActivity een functie te maken welke de GridView terug geeft. en in de onPostExecute de volgende code aan te roepen

CategoryFragment.java
Java:
1
GridView gridviewCategories = ((MainActivity) getActivity()).getGridViewCategories();


MainActivity.java
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MainActivity extends AppCompatActivity {
    private GridView mGridViewCategories;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        this.mGridViewCategories = (GridView) findViewById(R.id.gridviewProducts);
    }

    public GridView getGridViewCategories() {
        return this.mGridViewCategories;
    }
}


Maar het moet toch mogelijk zijn om de GridView op te halen vanuit de fragment/AsyncTask