【问题标题】:Android ListView does not display data on app first launchAndroid ListView 在应用首次启动时不显示数据
【发布时间】:2015-07-07 09:06:10
【问题描述】:

我的问题是 android ListView。 我设计了一个带有片段的android应用程序。在片段中有一个 ListView,它显示一些数据。此数据使用 AsyncTask 从服务器加载。当我第一次启动应用程序时(应用程序甚至没有安装在设备上),ListView 不显示任何项目。然后,例如,当我最小化应用程序并最大化它,或者在应用程序屏幕之间切换时,项目出现了。我已经探索了源代码几个小时,但无法解决问题。任何帮助将不胜感激。下面是我的应用程序代码。

MainActivity.java 类。

    public class MainActivity extends FragmentActivity implements         RateRefreshListener {
    private CurrencyConstants.RATE_TYPES currentTab;

    private int darkColor;
    private int lightColor;

    private String currentCurrency;
    private CurrencyConstants.SORTING currentSorting;

    private RateFragment currentFragment;
    private RateFragment banksFragment;
    private RateFragment exchangesFragment;

    private UserPreferences userPreferences;

    TextView bankOrExchange;

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

        bankOrExchange = ( TextView    )findViewById(R.id.bank_or_exchange);

        userPreferences = UserPreferences.sharedUserPreferences(this);

        darkColor = getResources().getColor(R.color.dark);
        lightColor = getResources().getColor(R.color.light);

        currentTab = CurrencyConstants.RATE_TYPES.EXCHANGE;
        currentCurrency = userPreferences.getCurrencyCode();
        currentSorting = userPreferences.getSortingCode();

        LinearLayout currencyLayout = (LinearLayout) findViewById(R.id.currency);

        for (int index = 0 ; index < currencyLayout.getChildCount() ; index++) {
            TextView currency = (TextView) currencyLayout.getChildAt(index);
            currency.setClickable(true);
            currency.setOnClickListener(currencyClickListener);

            if (userPreferences.getCurrencyCode().equals(CurrencyConstants.CURRENCIES[index])) {
                currency.setBackgroundColor(darkColor);
                currency.setTextColor(lightColor);
            } else {
                currency.setBackgroundResource(R.drawable.light_rect_outlined);
                currency.setTextColor(darkColor);
            }
        }

        LinearLayout sortingLayout = (LinearLayout) findViewById(R.id.sorting);

        for (int index = 0 ; index < sortingLayout.getChildCount() ; index++) {
            TextView sorting = (TextView) sortingLayout.getChildAt(index);
            sorting.setClickable(true);
            sorting.setOnClickListener(sortingClickListener);

            if (userPreferences.getSortingCode().equals(CurrencyConstants.SORTING.forIndex(index))) {
                sorting.setBackgroundColor(darkColor);
                sorting.setTextColor(lightColor);
            } else {
                sorting.setBackgroundResource(R.drawable.light_rect_outlined);
                sorting.setTextColor(darkColor);
            }
        }

        showBanks(null);

        APITalker.sharedTalker().refresh(DBTalker.sharedTalker(this), this);
    }


public void showBanks(View view) {

        if (currentTab.equals(CurrencyConstants.RATE_TYPES.BANK)) {
            return;
        }

        currentTab = CurrencyConstants.RATE_TYPES/**/.BANK;

        setupTabs(lightColor, darkColor);

        android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
        android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.setCustomAnimations(R.anim.from_left_slide_in, R.anim.to_right_slide_out);

        if (banksFragment == null) {
            banksFragment= RateFragment.newInstance(currentCurrency, currentSorting, currentTab);
            fragmentTransaction.add(R.id.rate_fragment_container, banksFragment);
        } else {
            banksFragment.setPreferences(currentCurrency, currentSorting);
            bankOrExchange.setText(R.string.bank);
            fragmentTransaction.replace(R.id.rate_fragment_container, banksFragment);
        }

        fragmentTransaction.addToBackStack(null);
        fragmentTransaction.commit();

        currentFragment = banksFragment;

    }



@Override
    public void rateRefreshSucceed() {
        userPreferences.setLastUpdate(new Date().getTime());
        currentFragment.setPreferences(currentCurrency, currentSorting);
    }

    @Override
    public void rateRefreshFail(String error) {

    }
}

APITalker.java 类,负责与服务器交互。

public class APITalker {
private final String BASE_URL = "SOME URL";
private final String INDEX_URL = BASE_URL + "/index";

private static APITalker sharedTalker;

private AsyncHttpClient client;

public static APITalker sharedTalker() {
    if (sharedTalker == null) {
        sharedTalker = new APITalker();
    }

    return sharedTalker;
}

private APITalker() {
    client = new AsyncHttpClient();
}

public void refresh(final DBTalker dbTalker, final RateRefreshListener listener) {
    client.get(INDEX_URL, new JsonHttpResponseHandler() {
        @Override
        public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
            super.onSuccess(statusCode, headers, response);
            dbTalker.store(response);
            listener.rateRefreshSucceed();
        }

        @Override
        public void onFailure(int statusCode, Header[] headers, String       responseString, Throwable throwable) {
            super.onFailure(statusCode, headers, responseString,   throwable);
        }
    });
}

片段,其中包含 ListView。

package com.flycode.restmobile.fragment;


import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;

import com.flycode.restmobile.R;
import com.flycode.restmobile.activity.MapActivity;
import com.flycode.restmobile.adapter.RateListAdapter;
import com.flycode.restmobile.constant.CurrencyConstants;
import com.flycode.restmobile.database.DBTalker;
import com.flycode.restmobile.model.Rate;

import java.util.ArrayList;

public class RateFragment extends Fragment implements ListView.OnItemClickListener {
    private static final String CURRENCY_CODE = "currencyCode";
    private static final String SORTING_CRITERIA = "sortingCriteria";
    private static final String RATE_TYPE = "rateType";

    private RateListAdapter rateListAdapter;
    private CurrencyConstants.RATE_TYPES rateType;

    public static RateFragment newInstance(String currencyCode, CurrencyConstants.SORTING sortingCriteria, CurrencyConstants.RATE_TYPES rateType) {
        RateFragment fragment = new RateFragment();
        Bundle args = new Bundle();
        args.putString(CURRENCY_CODE, currencyCode);
        args.putSerializable(SORTING_CRITERIA, sortingCriteria);
        args.putSerializable(RATE_TYPE, rateType);
        fragment.setArguments(args);
        return fragment;
    }

    public RateFragment() {
        super();
    }

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_rate, container, false);

        String currencyCode = getArguments().getString(CURRENCY_CODE);
        CurrencyConstants.SORTING sortingCriteria = (CurrencyConstants.SORTING) getArguments().getSerializable(SORTING_CRITERIA);
        rateType = (CurrencyConstants.RATE_TYPES) getArguments().getSerializable(RATE_TYPE);
        ArrayList<Rate> rates = DBTalker.sharedTalker(getActivity()).getRates(currencyCode, sortingCriteria, rateType);

        rateListAdapter = new RateListAdapter(getActivity(), rates);

        ListView ratesList = (ListView) view.findViewById(R.id.rate_list);
        ratesList.setAdapter(rateListAdapter);
        ratesList.setOnItemClickListener(this);

        return view;
    }

    public void setPreferences(String currencyCode, CurrencyConstants.SORTING sortingCriteria) {
        getArguments().putString(CURRENCY_CODE, currencyCode);
        getArguments().putSerializable(SORTING_CRITERIA, sortingCriteria);

        ArrayList<Rate> rates = DBTalker.sharedTalker(getActivity()).getRates(currencyCode, sortingCriteria, rateType);

        rateListAdapter.setRates(rates);
        rateListAdapter.notifyDataSetChanged();
    }


    /**
     * OnItemClickListener Methods
     */

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Rate rate = rateListAdapter.getItem(position);

        Intent mapIntent = new Intent(getActivity(), MapActivity.class);
        mapIntent.putExtra(MapActivity.RATE, rate);
        getActivity().startActivity(mapIntent);
    }
}

还有我的 Logcat 警告/错误输出

 07-07 13:34:29.357  15256-15256/com.flycode.restmobile E/ION﹕ ION_IOC_CUSTOM_GET_CONFIG ioctl Failed. Use default
07-07 13:34:29.417  15256-15256/com.flycode.restmobile W/JsonHttpResponseHandler﹕ onSuccess(int, Header[], JSONObject) was not overriden, but callback was received

【问题讨论】:

  • 你执行异步任务时我需要你的代码
  • 嗨,Sheychan。谢谢你的回复。 AsyncTask 通过调用 APITalker.sharedTalker().refresh(DBTalker.sharedTalker(this), this) 来执行;在 onCreate() 的最后一行。与服务器的交互在 APITalker 类 refresh() 函数中。
  • 最后一件事,我希望你在 logcat 上显示警告/错误
  • 是的,当然,只是片刻。 :)

标签: java android listview android-fragments android-listview


【解决方案1】:

第一次尝试启动片段时,数据库中不存在数据。所以一旦收到数据就需要刷新fragment。

您在活动中收到 refreshSucceeded 回调。在那里,您需要调用片段函数来通知片段数据已更改。然后从该片段函数中,您需要从 DBTalker 重新获取数据并调用 notify。

所需步骤:

  1. 在片段onDataRefreshed()中创建函数;

  2. 从活动 onRefreshSucceded() 函数调用 onDataRefreshed() 函数。

  3. 在片段的 onDataRefreshed() 函数中,进行必要的调用以从 DBTalker 获取数据并重新加载列表。

【讨论】:

  • Eldhose M Babu,但我想我可以通过调用片段的 setPreferences 函数来实现您所说的。还是不行?
猜你喜欢
  • 2018-08-31
  • 2015-09-20
  • 1970-01-01
  • 2021-12-08
  • 1970-01-01
  • 1970-01-01
  • 2016-10-09
  • 2014-01-16
  • 1970-01-01
相关资源
最近更新 更多