0

我手头有一个奇怪的 ListView 显示问题。我的应用程序显示状态图标和商店地址列表。列表的每一行都包含一个图像视图和一个文本视图。可以通过选择不同的日期来更改 ListView 显示。日期由 ListView 上方的单选按钮组选择。他们是昨天、今天和明天。

ListView 显示在针对皮肤 WQVGA400 的 Google API 级别 17 的模拟器中运行良好。但是,它在 Galaxy S3 手机上仅显示昨天和今天的空白行。该行的图标和文本在那里,我可以通过单击一行来验证并在弹出窗口中查看内容。ListView 在 Galaxy S3 上一直适用于明天的数据。我的应用程序清单文件指定了 android:minSdkVersion="14" 和 android:targetSdkVersion="17"。我的 ListView 充满了自定义适配器。

我在互联网上做了很多研究,但找不到答案。我怀疑这与内存问题有关。谁能帮助回答如何解决这个缺陷?提前致谢。

这是一些相关的代码。希望他们提供足够的信息。

  1. 包含 ListView 的片段 XML:

    <RadioGroup
        android:id="@+id/radioVisitDate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:orientation="horizontal">
    
        ...
    
    </RadioGroup>
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:background="#1BD6E0">
    
         <TextView android:id="@+id/visit_status_header"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:foreground="#000000"
            android:text="@string/visit_status"
        />
    
        ...
    
    </LinearLayout>
    
    <ListView 
        android:id="@android:id/list" 
        android:layout_width="match_parent" 
        android:layout_height="fill_parent"
        android:background="#FFFFFF"
        android:drawSelectorOnTop="false"/> 
    

  2. 片段的代码文件:

...

public class PugsMobileStoreStopsFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor>
{
    public interface OnFragmentEventsListener 
    {
        public void onCursorLoadStatus(Intent loadStatusIntent);
        public void onGetStoreStopsServiceStart(Intent startGetStoreStopsServiceIntent);
        public void OnUserSettingsErrorListener(Intent correctUserSettingsIntent);
    }

    private OnFragmentEventsListener fragmentEventListener;
    private Intent loadStatusIntent = null;
    private Intent getStoreStopsServiceStatusIntent = null;
    private Intent getOrderLineItemsIntent = null;
    private Intent correctUserSettingsIntent = null;
    private Handler handler = new Handler();
    private SparseArray<PugsMobileStoreStopInfo> storeStopInfos = null;
    private PugsMobileStoreStopsAdapter storeStopInfosAdapter;
    private ListView storeStopsListView = null;
    private Calendar visitDate = Calendar.getInstance();
    private boolean tomorrowSeleted = false;
    private SharedPreferences prefs = null;
    private SharedPreferences.Editor prefsEditor;
    private int salesRepNumber = 0;
    private boolean salesRepNumEmptyAlertDisplayed = false;
    private boolean salesRepNumNonNumericAlertDisplayed = false;
    private SharedPreferences sharedPref = null;
    private SharedPreferences.Editor editor = null;
    private int selectedBtnId = 0;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    {
        View view = inflater.inflate(R.layout.pugs_mobile_store_stops_fragment, null); 
        storeStopsListView = (ListView) view.findViewById(android.R.id.list);
        storeStopsListView.setItemsCanFocus(false);
        setHasOptionsMenu(true);
        return view; 
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) 
    {
        super.onActivityCreated(savedInstanceState);
        storeStopInfos = new SparseArray<PugsMobileStoreStopInfo>();
        getLoaderManager().initLoader(PugsMobileConstansDefinition.DataRequester.ENUM_STORE_VISIT.ordinal(), null, this);  
        RadioGroup daySelectionRadiogroup = (RadioGroup)getActivity().findViewById(R.id.radioVisitDate);
        restoreVisitDateSelection();

        daySelectionRadiogroup.setOnCheckedChangeListener(new OnCheckedChangeListener(){
            public void onCheckedChanged(RadioGroup group, int radioButtonId) {
                // checkedId is the RadioButton selected
                switch(radioButtonId) 
                {
                    case R.id.radioYesterday:
                        tomorrowSeleted = false;
                        visitDate = PugsMobileUtilities.getYesterday();
                        resetStoreStopListView();
                        break;
                    case R.id.radioToday:
                         tomorrowSeleted = false;
                         visitDate = Calendar.getInstance();
                         resetStoreStopListView();
                         break;
                    case R.id.radioTomorrow: 
                        tomorrowSeleted = true;
                        visitDate= PugsMobileUtilities.getTomorrow();
                        resetStoreStopListView();
                        break;

                    default:
                        break;
                }              
            }
        });

        Thread t = 
            new Thread(new Runnable(){
                        public void run() 
                        {
                            updateStoreStops(); 
                        }
                     });
        t.start();
    }

    private void restoreVisitDateSelection()
    {   
        if (selectedBtnId > 0)
        {
            ((RadioButton) getActivity().findViewById(selectedBtnId)).setSelected(true);
        }
    }

    private void resetStoreStopListView()
    {
        handler.post(new Runnable(){
               public void run() 
               {
                   storeStopsListView.setAdapter(null);

                   getLoaderManager().restartLoader(PugsMobileConstansDefinition.DataRequester.ENUM_STORE_VISIT.ordinal(), null, PugsMobileStoreStopsFragment.this);
               }
             });
    }

    public void saveFragmentVariaqbles()
    {
        sharedPref = getActivity().getSharedPreferences(PugsMobileConstansDefinition.PUGS_MOBILE_SHARED_PREF, getActivity().MODE_PRIVATE);

        if (null != sharedPref)
        {
            RadioGroup g = (RadioGroup) getActivity().findViewById(R.id.radioVisitDate); 
            selectedBtnId = g.getCheckedRadioButtonId();

            editor = sharedPref.edit();
            editor.putInt(PugsMobileConstansDefinition.SELECTED_VISIT_DATE_RADIO_BUTTON, selectedBtnId);
            editor.commit();
        }
    }

    ...

    public void updateStoreStops() 
    {   
        boolean bRemovePreviousSalesRepData = false;
        Integer salesRepNumber = getSalesRepNumber();
        int prevSalesRepNumber = getPreviousSalesRepNumber();

        if (salesRepNumber == PugsMobileConstansDefinition.EMPTY_TEXT_ERR_CODE || salesRepNumber == PugsMobileConstansDefinition.NON_NUMERIC_TEXT_ERR_CODE )
        {
            return;
        }

        if (prevSalesRepNumber == salesRepNumber.intValue())
        {
            handler.post(new Runnable() {
                public void run() {
                    getLoaderManager().restartLoader(PugsMobileConstansDefinition.DataRequester.ENUM_STORE_VISIT.ordinal(), null, PugsMobileStoreStopsFragment.this);  
                }
            }); 
        }
        else
        {
            prefsEditor = prefs.edit();
            prefsEditor.putString(UserSettingsActivity.SETTINGS_PREVIOUS_ROUTE_NUMBER,salesRepNumber.toString());
            prefsEditor.commit();

            if (prevSalesRepNumber > 0)
            {
                bRemovePreviousSalesRepData = true;
            }

            startDataService(PugsMobileConstansDefinition.DataRequester.ENUM_STORE_VISIT.ordinal(), bRemovePreviousSalesRepData);
        }
    }

    public void updateStoreVisitListView()
    {
        requestStoreStopsInfo();
    }

    @Override
    public void onAttach(Activity activity) 
    {
        super.onAttach(activity);

        try 
        {
            fragmentEventListener = (OnFragmentEventsListener) activity;
        } 
        catch (ClassCastException e) 
        {
            throw new ClassCastException(activity.toString() + " must implement OnFragmentEventsListener");
        }

    }

    public Loader<Cursor> onCreateLoader(int id, Bundle args) 
    {
        CursorLoader loader = null;

        if (IsSalesRepNumberValid())
        {
            ...
        }           
        return loader;
    }

    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) 
    {
        retrieveDataFromCursor(cursor,loader.getId());
    }

    public void onLoaderReset(Loader<Cursor> loader) 
    {
        switch(PugsMobileConstansDefinition.dataRequesterEnums[loader.getId()])
        {
            case ENUM_STORE_VISIT: storeStopsListView.setAdapter(null);
              break;

            default:
                break;
        }
    }

    private CursorLoader getStoreStopsLoader()
    {   
        ...
        return loader;
    }

    private CursorLoader getRefreshStoreStopsLoader()
    {   
        ...
        return loader;
    }

    private void processStoreStopsData(Cursor cursor)
    {
        int count = 0;

        try
        {
            if (null != cursor)
            {
                String storeAddress = null;
                int visitStatus = 0;
                int rowIndex = -1;
                PugsMobileStoreStopInfo storeStopInfo = null;
                count = cursor.getCount();

                if (0 == count)
                {
                    return;
                }

                if (null != storeStopInfos)
                {
                    storeStopInfos.clear();
                    storeStopInfos = null;
                }

                storeStopInfos = new SparseArray<PugsMobileStoreStopInfo>();
                PugsMobileAlarmReceiver.geoDataList.clear();

                while(cursor.moveToNext())
                {
                    rowIndex = cursor.getPosition();

                    storeStopInfo = new PugsMobileStoreStopInfo();
                    storeStopInfo.setStoreName(cursor.getString(cursor.getColumnIndexOrThrow(PugsMobileStoreVisitInfoTable.COLUMN_STORE_NAME)));

                    storeAddress += " ";
                    storeAddress = cursor.getString(cursor.getColumnIndexOrThrow(PugsMobileStoreVisitInfoTable.COLUMN_STREET_ADDRESS));
                    storeAddress += ", " + cursor.getString(cursor.getColumnIndexOrThrow(PugsMobileStoreVisitInfoTable.COLUMN_STORE_CITY));
                    storeAddress += ", " + cursor.getString(cursor.getColumnIndexOrThrow(PugsMobileStoreVisitInfoTable.COLUMN_STORE_STATE));

                    storeStopInfo.setStoreAddress(storeAddress);

                    visitStatus = cursor.getInt(cursor.getColumnIndexOrThrow(PugsMobileStoreVisitInfoTable.COLUMN_VISIT_STATUS));

                    if (tomorrowSeleted)
                    {
                        visitStatus = 3;
                    }

                    storeStopInfo.setStoreVisitStatus(visitStatus);         
                    storeStopInfo.setStoreId(cursor.getInt(cursor.getColumnIndexOrThrow(PugsMobileStoreVisitInfoTable.COLUMN_STORE_ID)));
                    storeStopInfo.setListHeaderId(cursor.getInt(cursor.getColumnIndexOrThrow(PugsMobileStoreVisitInfoTable.COLUMN_LISTHEADER_ID)));
                    storeStopInfo.setBillId(cursor.getInt(cursor.getColumnIndexOrThrow(PugsMobileStoreVisitInfoTable.COLUMN_STORE_BILL_ID)));

                    PugsGeoDataInfo storeGeoInfo = new PugsGeoDataInfo();
                    storeGeoInfo.setLatitude(Double.parseDouble(cursor.getString(cursor.getColumnIndexOrThrow(PugsMobileStoreVisitInfoTable.COLUMN_STORE_LATITUDE))));
                    storeGeoInfo.setLongitude(Double.parseDouble(cursor.getString(cursor.getColumnIndexOrThrow(PugsMobileStoreVisitInfoTable.COLUMN_STORE_LONGITUDE))));
                    PugsMobileAlarmReceiver.geoDataList.add(storeGeoInfo);//Save store geo data 

                    storeStopInfos.append(rowIndex, storeStopInfo);
                }

                if (null != storeStopInfos.get(0))
                {
                    handler.post(new Runnable(){public void run() {populateStoreStopsList(storeStopInfos);}});
                }
                else
                {
                    updateStoreStops();
                }
            }           
        }
        catch(Exception e)
        {
            e.fillInStackTrace();
        }
    }

    private synchronized void retrieveDataFromCursor(Cursor cursor, int dataRequesterID)
    {
        loadStatusIntent = null;
        loadStatusIntent = new Intent();
        loadStatusIntent.setAction(PugsMobileConstansDefinition.LOAD_FINISHED);
        fragmentEventListener.onCursorLoadStatus(loadStatusIntent);

        switch(PugsMobileConstansDefinition.dataRequesterEnums[dataRequesterID])
        {   
            case ENUM_STORE_VISIT:
                 processStoreStopsData(cursor);
              break;
            case ENUM_REFRESH_STORE_VISIT:  
                 processStoreStopsData(cursor);     
              break;

            default:
                break;
        }
    }

    private void populateStoreStopsList(SparseArray<PugsMobileStoreStopInfo> storeStops)
    {
        //Initialize the adapter sending the current context
        storeStopInfosAdapter = new PugsMobileStoreStopsAdapter(getActivity(), storeStops);
        storeStopInfosAdapter.notifyDataSetChanged();
        storeStopsListView.setAdapter(storeStopInfosAdapter); 
    }

    private void startDataService(int dataType, boolean bRemovePreviousSalesRepData)
    {
        Intent dataIntent = new Intent(getActivity(), PugsMobileDataService.class);

        ...
        getActivity().startService(dataIntent); 
    }

    /* @param variableName - name of drawable, e.g R.drawable.<b>image</b>
     * @param � - class of resource, e.g R.drawable, of R.raw
     * @return integer id of resource
    */
    public static int getResId(String variableName, Class<?> c)
    {
        Field field = null;
        int resId = 0;

        try 
        {               
            field = c.getField(variableName);

            try 
            {
                resId = field.getInt(null);
            } 
            catch (Exception e) 
            {
                e.printStackTrace();
            }
         } 
         catch (Exception e) 
         {
            e.printStackTrace();
         }

         return resId;
     }

    public int getSalesRepNumber()
    {
        prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
        String strSalesRepNum = prefs.getString(UserSettingsActivity.SETTINGS_ROUTE_NUMBER, "none");
        strSalesRepNum.trim();

        if (strSalesRepNum.equalsIgnoreCase("none"))
        {       
            return PugsMobileConstansDefinition.EMPTY_TEXT_ERR_CODE;
        }
        else if (!isNumeric(strSalesRepNum))
        {
            //salesRepNumEmptyAlertDisplayed = false;   
            salesRepNumNonNumericAlertDisplayed = false;
            return PugsMobileConstansDefinition.NON_NUMERIC_TEXT_ERR_CODE;
        }

        return Integer.parseInt(strSalesRepNum);

    }

    public int getPreviousSalesRepNumber()
    {
        prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
        String strSalesRepNum = prefs.getString(UserSettingsActivity.SETTINGS_PREVIOUS_ROUTE_NUMBER, "none");
        strSalesRepNum.trim();

        if (strSalesRepNum.equalsIgnoreCase("none"))
        {
            return 0;
        }

        return Integer.parseInt(strSalesRepNum);
    }

    public boolean isNumeric(String s) 
    {  
        return s.matches("\\d+");  
    } 

    public void requestStoreStopsInfo()
    {
        getStoreStopsServiceStatusIntent = null;
        getStoreStopsServiceStatusIntent = new Intent();
        getStoreStopsServiceStatusIntent.setAction(PugsMobileConstansDefinition.PUGS_MOBILE_MESSAGE_SENT_ACTION);
        getStoreStopsServiceStatusIntent.putExtra(PugsMobileConstansDefinition.PUGS_MOBILE_MESSAGE_EXTRA, PugsMobileConstansDefinition.STORE_STOPS_SERVICE_STARTED);
        fragmentEventListener.onGetStoreStopsServiceStart(getStoreStopsServiceStatusIntent);

        //If SQLite db is empty, then get data from SQL server
        Thread t = new Thread(new Runnable() {
            public void run() {                                 
                startDataService(PugsMobileConstansDefinition.DataRequester.ENUM_STORE_VISIT.ordinal(), false);
            }
        });

        t.start();  
    }

    public void requestLineItemsInfo()
    {
        getOrderLineItemsIntent = null;
        getOrderLineItemsIntent = new Intent();
        getOrderLineItemsIntent.setAction(PugsMobileConstansDefinition.PUGS_MOBILE_MESSAGE_SENT_ACTION);
        getOrderLineItemsIntent.putExtra(PugsMobileConstansDefinition.PUGS_MOBILE_MESSAGE_EXTRA, PugsMobileConstansDefinition.ORDER_LINE_ITEMS_SERVICE_STARTED);
        fragmentEventListener.onGetStoreStopsServiceStart(getOrderLineItemsIntent);

        //If SQLite db is empty, then get data from SQL server
        Thread t = new Thread(new Runnable() {
            public void run() {                                 
                startDataService(PugsMobileConstansDefinition.DataRequester.ENUM_ORDER_LINE_ITEMS.ordinal(), false);
            }
        });

        t.start();  
    }

    private boolean IsSalesRepNumberValid()
    {
        boolean bValid = true;  

        salesRepNumber = getSalesRepNumber();
        correctUserSettingsIntent = null;
        correctUserSettingsIntent = new Intent();
        correctUserSettingsIntent.putExtra(PugsMobileConstansDefinition.SALESREP_NUMBER_EMPTY, false);
        correctUserSettingsIntent.putExtra(PugsMobileConstansDefinition.SALESREP_NUMERIC_ID_NEEDED, false);

        if (PugsMobileConstansDefinition.EMPTY_TEXT_ERR_CODE == salesRepNumber)
        {
            if (!salesRepNumEmptyAlertDisplayed)
            {           
                correctUserSettingsIntent.putExtra(PugsMobileConstansDefinition.SALESREP_NUMBER_EMPTY, true);
                fragmentEventListener.OnUserSettingsErrorListener(correctUserSettingsIntent);
                salesRepNumEmptyAlertDisplayed = true;      
            }   
            bValid = false; 
        }
        else if (PugsMobileConstansDefinition.NON_NUMERIC_TEXT_ERR_CODE == salesRepNumber)
        {
            if (!salesRepNumNonNumericAlertDisplayed)
            {
                correctUserSettingsIntent.putExtra(PugsMobileConstansDefinition.SALESREP_NUMERIC_ID_NEEDED, true);
                fragmentEventListener.OnUserSettingsErrorListener(correctUserSettingsIntent);
                salesRepNumNonNumericAlertDisplayed = true;
            }   
            bValid = false; 
        }

        return bValid;
    }   
}
  1. 填充列表视图的自定义适配器代码

……

public class PugsMobileStoreStopsAdapter extends BaseAdapter implements OnClickListener 
{
    private SparseArray<PugsMobileStoreStopInfo> storeStops = null;
    private LayoutInflater mInflater;
    private ViewHolder holder = null;
    private Context context = null;

    public PugsMobileStoreStopsAdapter(Context context, SparseArray<PugsMobileStoreStopInfo> storeStopInfos) 
    {
        if (null != storeStops)
        {
            storeStops.clear();
            storeStops = null;
        }

        this.storeStops = storeStopInfos;
        this.context = context; 
        mInflater = LayoutInflater.from(context);   
    }

    public int getCount() 
    {     
        return storeStops.size();    
    }


    public PugsMobileStoreStopInfo getItem(int position)
    {
        return storeStops.get(position);
    }

    public long getItemId(int position)
    {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
    {
        if (convertView == null) 
        { 
            holder = null;
            holder = new ViewHolder();  
            mInflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = mInflater.inflate(R.layout.pugsmobile_store_stop_row_layout, parent,false);

            holder.storeVisitStatus   = (ImageView) convertView.findViewById(R.id.storeVisitStatus);
            holder.storeNameAddress   = (TextView) convertView.findViewById(R.id.storeNameAddress);
            holder.storeId            = (TextView) convertView.findViewById(R.id.storeId);
            holder.listHeaderId       = (TextView) convertView.findViewById(R.id.listHeaderId);
            holder.billId             = (TextView) convertView.findViewById(R.id.billId);

            convertView.setTag(holder);  
            convertView.setOnClickListener(new onItemClickListener(position));    
        }
        else 
        {
           holder = (ViewHolder) convertView.getTag();
        } 

        holder.storeNameAddress.setText(storeStops.get(position).getStoreName() + ", " + storeStops.get(position).getStoreAddress());
        holder.storeId.setText(storeStops.get(position).getStoreId().toString());
        holder.listHeaderId.setText(storeStops.get(position).getListHeaderId().toString());
        holder.billId.setText(storeStops.get(position).getBillId().toString());

        switch(storeStops.get(position).getStoreVisitStatus())
        {
            case 0: 
                holder.storeVisitStatus.setImageResource(R.drawable.redicon);
              break;

            case 1:
                holder.storeVisitStatus.setImageResource(R.drawable.yellowicon);
                  break;

            case 2:
                holder.storeVisitStatus.setImageResource(R.drawable.greenicon);
                  break;

            case 3:
                holder.storeVisitStatus.setImageResource(R.drawable.greyicon);
                  break;

            default:
                break;
        }

        return convertView;
    }

    @Override
    public void onClick(View v) 
    {
        Log.v("TAG", "Row button clicked");
    }

    public static class ViewHolder 
    {
        ImageView storeVisitStatus;
        TextView  storeNameAddress; 
        TextView  storeId;
        TextView  listHeaderId;
        TextView  billId;
    }

    private class onItemClickListener implements OnClickListener
    {       
        private int mPosition;

        onItemClickListener(int position)
        {
            mPosition = position;
        }

        @Override
        public void onClick(View arg0) 
        {
            ViewHolder holder =(ViewHolder)arg0.getTag();
            StringTokenizer tokens = new StringTokenizer((String)holder.storeNameAddress.getText(), ",");
            String storeName = tokens.nextToken();// this will contain store name alone

            Intent launchOrderTypeSelectionIntent = new Intent(context, PugsMobileNewOrderActivity.class);
            launchOrderTypeSelectionIntent.putExtra(PugsMobileConstansDefinition.STORE_NAME, storeName);
            launchOrderTypeSelectionIntent.putExtra(PugsMobileConstansDefinition.PUGSMOBILE_STORE_ID, Integer.parseInt((String)holder.storeId.getText()));  
            launchOrderTypeSelectionIntent.putExtra(PugsMobileConstansDefinition.PUGSMOBILE_LIST_HEADER_ID, Integer.parseInt((String)holder.listHeaderId.getText()));
            launchOrderTypeSelectionIntent.putExtra(PugsMobileConstansDefinition.PUGSMOBILE_BILL_ID, Integer.parseInt((String)holder.billId.getText()));

            context.startActivity(launchOrderTypeSelectionIntent);

            /*
             String[] projection = 
                    new String[] {PugsMobileStoreVisitInfoTable.COLUMN_STORE_NAME,
                                  PugsMobileStoreVisitInfoTable.COLUMN_STORE_ID
                                 };  
            String where = PugsMobileStoreVisitInfoTable.COLUMN_STORE_ID + " = " + storeIdText;

            ContentResolver cr = context.getContentResolver();  
            Cursor result = cr.query(PugsMobileConstansDefinition.STORE_VISIT_INFO_CONTENT_URI, projection, where, null, null);

            try
            {
                if (result.moveToFirst()) 
                {
                    String storeName = result.getString(result.getColumnIndexOrThrow(PugsMobileStoreVisitInfoTable.COLUMN_STORE_NAME));
                    int storeId = Integer.parseInt(result.getString(result.getColumnIndexOrThrow(PugsMobileStoreVisitInfoTable.COLUMN_STORE_ID)));

                    Intent launchOrderTypeSelectionIntent = 
                            new Intent(context, PugsMobileOrderTypeSelectionActivity.class);
                    launchOrderTypeSelectionIntent.putExtra(PugsMobileConstansDefinition.STORE_NAME, storeName);
                    launchOrderTypeSelectionIntent.putExtra(PugsMobileConstansDefinition.PUGSMOBILE_STORE_ID, storeId);                 
                    context.startActivity(launchOrderTypeSelectionIntent);
                }
            }
            catch(Exception e)
            {
                e.fillInStackTrace();
            }*/
            //Log.v(TAG, "onItemClick at position" + mPosition);          
        }       
    }
}
4

0 回答 0