Android ListView不会在应用首次启动时显示数据

时间:2015-07-07 09:06:10

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

我的问题是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

1 个答案:

答案 0 :(得分:1)

第一次,当您尝试启动片段时,数据不存在于DB中。因此,您需要在收到数据后刷新片段。

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

所需步骤:

  1. 在片段onDataRefreshed();

  2. 中创建一个函数
  3. 从activity onRefreshSucceded()函数调用onDataRefreshed()函数。

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