notifyDataSetChanged()不会影响我的adapterView

时间:2017-05-18 22:27:43

标签: java android

我是Android的新手,我必须为我的最终项目创建一个Android应用程序。

我正在制作一个刷卡应用程序,我正在使用'com.lorentzos.swipecards:library:1.0.9'库用于滑动引擎。

它使用一个自定义适配器来扩展基本适配器以扩展布局文件,并使用来自ArrayList的iformation填充某些ImageView和TextView。

这是适配器的代码

package com.botevplovdiv.foodmatch2;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Stelio on 13.5.2017 г..
 */



public class MyAppAdapter extends BaseAdapter {

    private static class ViewHolder {
        public FrameLayout background;
        public TextView DataText;
        public ImageView cardImage;
        public TextView shortDescriptionTextView;
        public TextView title;
    }
    ;
    public List<FoodDish> dishesList = new ArrayList<>();
    public Context mContext;

    public MyAppAdapter(Context context, List<FoodDish> foodDishes) {
        this.dishesList = foodDishes;
        this.mContext = context;
    }



    @Override
    public int getCount() {
        return dishesList.size();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

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

    public List<FoodDish> getDishesList(){
        return this.dishesList;
    }

    public void updateReceiptsList(List<FoodDish> newlist) {
        dishesList.clear();
        dishesList.addAll(newlist);
        this.notifyDataSetChanged();
    }


    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        FoodDish current = dishesList.get(position);

        ViewHolder viewHolder;


        if (convertView == null) {

            LayoutInflater inflater = LayoutInflater.from(mContext);
            convertView = inflater.inflate(R.layout.cards_layout, parent,false);
            // configure view holder
            viewHolder = new ViewHolder();
            viewHolder.DataText = (TextView) convertView.findViewById(R.id.priceText);
            viewHolder.background = (FrameLayout) convertView.findViewById(R.id.background);
            viewHolder.cardImage = (ImageView) convertView.findViewById(R.id.cardImage);
            viewHolder.shortDescriptionTextView = (TextView) convertView.findViewById(R.id.shortDescription);
            viewHolder.title = (TextView) convertView.findViewById(R.id.titleText);

            convertView.setTag(viewHolder);

        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.DataText.setText(current.getPrice());
        viewHolder.title.setText(current.getTitle());
        viewHolder.shortDescriptionTextView.setText(current.getDescription());
        Glide.with(mContext).load(current.getImagePath()).into(viewHolder.cardImage);



        return convertView;
    }
}

一切都很好,直到一点。

我有一个设置活动,它会使一个有一堆交换机的preferences.xml膨胀。我可以使用MultiSelectListPreferences做到这一点,但出于美观原因,我希望使用开关。

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

<PreferenceCategory
    android:selectable="true"
    android:title="@string/food_categories_name">

    <SwitchPreference
        android:defaultValue="true"
        android:key="fishSwitch"
        android:title="Fish" />
    <SwitchPreference
        android:defaultValue="true"
        android:key="meatSwitch"
        android:title="Meat" />
    <SwitchPreference
        android:defaultValue="true"
        android:key="vegSwitch"
        android:title="Vegeterian" />
    <SwitchPreference
        android:defaultValue="true"
        android:key="pizzaSwitch"
        android:title="Pizza" />
    <SwitchPreference
        android:defaultValue="true"
        android:key="pastaSwitch"
        android:title="Pasta" />
</PreferenceCategory>

<ListPreference
    android:defaultValue="@array/area_list"
    android:entries="@array/area_list"
    android:entryValues="@array/area_list"
    android:key="list_preference_1"
    android:title="@string/areas" />
<PreferenceCategory android:title="@string/venues_categories">

    <SwitchPreference
        android:defaultValue="true"
        android:key="restaurantSwitch"
        android:title="Restaurants" />
    <SwitchPreference
        android:defaultValue="true"
        android:key="takeAwaySwitch"
        android:title="Take Away" />
</PreferenceCategory>

在我的MainActivity中,我有prefereceChangedListner,它通过尊重的方法注册更改并优化searcCriteria和refineList列表。

package com.botevplovdiv.foodmatch2;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.preference.SwitchPreference;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;

import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.lorentzos.flingswipe.SwipeFlingAdapterView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class MainActivity extends AppCompatActivity {

    // keys for reading data from SharedPreferences
    public static final String FISH = "fishSwitch";
    public static final String MEAT = "meatSwitch";
    public static final String VEGETARIAN = "vegSwitch";
    public static final String PIZZA = "pizzaSwitch";
    public static final String PASTA = "pastaSwitch";
    public static final String RESTAURANTS = "restaurantSwitch";
    public static final String TAKEAWAY = "takeAwaySwitch";


    private MyAppAdapter myAppAdapter;
    private List<FoodDish> dishList;
    private List<FoodDish> refineList;
    private List<FoodDish> dumpList;
    private List<Venue> venues;
    private boolean[] booleans;
    private String[] booleansTags;
    private List<String> searchCriteria;
    private SwipeFlingAdapterView flingContainer;
    public static Map<String, Bitmap> bitmaps = new HashMap<>();
    boolean fishSwitch;
    boolean meatSwitch;
    boolean vegetarianSwitch;
    boolean pizzaSwitch;
    boolean pastaSwitch;
    boolean restaurantSwitch;
    boolean takeAwaySwitch;
    boolean preferenceChanged = true;
    String TAG = "FoodMatch";



    @Override
     protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        flingContainer = (SwipeFlingAdapterView) findViewById(R.id.frame);


        // set default values in the app's SharedPreferences
        PreferenceManager.setDefaultValues(this, R.xml.preferences, false);

        // register listener for SharedPreferences changes
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        sharedPreferences.registerOnSharedPreferenceChangeListener(
                preferencesChangeListener);

        fishSwitch = sharedPreferences.getBoolean(FISH,false);
        meatSwitch =  sharedPreferences.getBoolean(MEAT,false);
        vegetarianSwitch =  sharedPreferences.getBoolean(VEGETARIAN,false);
        pizzaSwitch =  sharedPreferences.getBoolean(PIZZA,false);
        pastaSwitch =  sharedPreferences.getBoolean(PASTA,false);
        restaurantSwitch =  sharedPreferences.getBoolean(RESTAURANTS,false);
        takeAwaySwitch =  sharedPreferences.getBoolean(TAKEAWAY,false);

        booleansTags = new String[] {"FISH","MEAT","VEGETARIAN","PIZZA","PASTA","RESTAURANT","TAKE AWAY"};

        dishList = new ArrayList<>();
        searchCriteria = new ArrayList<>();
        refineList = new ArrayList<>();
        dumpList = new ArrayList<>();


        // load initial data
        loadDishes();

        createSearchCriteria(searchCriteria);
        refineDishesList();

        //lock the device to portrait mode
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        myAppAdapter = new MyAppAdapter(this, refineList);
        flingContainer.setAdapter(myAppAdapter);
        flingContainer.setFlingListener(new SwipeFlingAdapterView.onFlingListener() {
            @Override
            public void removeFirstObjectInAdapter()
            {

            }

            @Override
            public void onLeftCardExit(Object dataObject)
            {
                FoodDish current = refineList.get(0);
                refineList.remove(0);
                myAppAdapter.notifyDataSetChanged();
                }
            }

            @Override
            public void onRightCardExit(Object dataObject)
            {
                FoodDish current = refineList.get(0);
                Intent intent = new Intent(MainActivity.this,LikedProduct.class).putExtra("current",current);
                startActivity(intent);
                refineList.remove(0);
                myAppAdapter.notifyDataSetChanged();

            }

            @Override
            public void onAdapterAboutToEmpty(int itemsInAdapter)
            {

            }

            @Override
            public void onScroll(float scrollProgressPercent) {
                View view = flingContainer.getSelectedView();
                view.findViewById(R.id.background).setAlpha(0);
                view.findViewById(R.id.item_swipe_left_indicator).setAlpha(scrollProgressPercent < 0 ? -scrollProgressPercent : 0);
                view.findViewById(R.id.item_swipe_right_indicator).setAlpha(scrollProgressPercent > 0 ? scrollProgressPercent : 0);
            }
        });


        // Listener for touching events
        flingContainer.setOnItemClickListener(new SwipeFlingAdapterView.OnItemClickListener()
        {
            @Override
            public void onItemClicked(int itemPosition, Object dataObject) {

                View view = flingContainer.getSelectedView();
                view.findViewById(R.id.background).setAlpha(0);
                myAppAdapter.notifyDataSetChanged();
            }
        });

        //floating buttons for remote flipping the cards

        FloatingActionButton yesFAB =
                (FloatingActionButton) findViewById(R.id.acceptButton);
        yesFAB.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!refineList.isEmpty())
                    flingContainer.getTopCardListener().selectRight();

            }
        });

        FloatingActionButton noFAB =
                (FloatingActionButton) findViewById(R.id.rejectButton);
        noFAB.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!refineList.isEmpty())
                    flingContainer.getTopCardListener().selectLeft();

            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i(TAG,"Entered onStart() method in MainActivity");

        if (preferenceChanged){
            myAppAdapter.notifyDataSetChanged();
            preferenceChanged = false;
        }
    }

    private void refineDishesList() {
        if (this.refineList.size() > 0)
        {
            this.refineList.clear();
        }
        for (FoodDish dish : this.dishList){
            if (this.searchCriteria.contains(dish.getCategory().toUpperCase()) && this.searchCriteria.contains(dish.getVenueType().toUpperCase())){
                this.refineList.add(dish);
            }
        }
    }

    private void createSearchCriteria(List<String> searchCriteria){
        booleans = new boolean[]{fishSwitch,meatSwitch,vegetarianSwitch,pizzaSwitch,pastaSwitch,restaurantSwitch,takeAwaySwitch};
        if (searchCriteria.size() >0){
            searchCriteria.clear();
        }
        for (int i = 0;i < booleansTags.length;i++){
            boolean temp = booleans[i];
            if (temp){
                searchCriteria.add(booleansTags[i]);
            }
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        Intent preferencesIntent = new Intent(this, Settings.class);
        startActivity(preferencesIntent);
        return super.onOptionsItemSelected(item);
    }

    public void loadDishes(){
        dishList.add(new FoodDish("Shrimp dish","https://cdn.pixabay.com/photo/2015/04/10/00/41/food-715539_960_720.jpg",getString(R.string.test),"Price : 2,14", "FISH","Restaurant"));
        dishList.add(new FoodDish("Pizza ultra mega qkata rabota","http://www.seattleorganicrestaurants.com/vegan-whole-foods/images/Food-Guidelines.jpg","Test description.This a very tasty dish and you should definitely order it.I don`t know what are you waiting for", "Price: 3,87", "PIZZA","Take Away"));
        dishList.add(new FoodDish("Pasta","http://assets.simplyrecipes.com/wp-content/uploads/2008/03/pasta-tuna-arugula-horiz-a-1600.jpg",getString(R.string.test), "Price: 4,87","PASTA","Restaurant"));
        dishList.add(new FoodDish("Chicken wings","http://cf.yellowblissroad.com/wp-content/uploads/2015/02/Baked-Chicken-Wings.jpg",getString(R.string.test),"Price: 1,23","MEAT","Take Away"));
        dishList.add(new FoodDish("Fish","http://cdn.skim.gs/image/upload/v1456339187/msi/grilled-catfish_izglgf.jpg",getString(R.string.test), "Price: 5,87", "FISH","Take Away"));
        dishList.add(new FoodDish("Spaghetti","http://food.fnr.sndimg.com/content/dam/images/food/fullset/2009/6/12/2/FO1D41_23785_s4x3.jpg.rend.hgtvcom.616.462.jpeg",getString(R.string.test), "Price: 9,23", "PASTA","Restaurant"));
        dishList.add(new FoodDish("Ceasar salad","http://entomofarms.com/wp-content/uploads/2016/04/EF-caesar-salad-cricket-powder.jpg",getString(R.string.test), "Price: 3,45", "VEGETARIAN","Restaurant"));
        dishList.add(new FoodDish("Steak sandwich","http://s3.amazonaws.com/finecooking.s3.tauntonclud.com/app/uploads/2017/04/18125307/051120015-01-steak-sandwich-recipe-main.jpg",getString(R.string.test), "Price: 3,45","MEAT","Take Away"));
        dishList.add(new FoodDish("Lasagna","http://www.weightlossresources.co.uk/img/recipes/vegetarian-dishes.jpg",getString(R.string.test), "Price: 11,45","VEGETERIAN","Restaurant"));
        dishList.add(new FoodDish("Sea Food Risotto","http://www.dvo.com/recipe_pages/healthy/Lemony_Seafood_Risotto.jpg",getString(R.string.test), "Price: 8,45","VEGETERIAN","Take Away"));
    }


    private SharedPreferences.OnSharedPreferenceChangeListener preferencesChangeListener =
            new SharedPreferences.OnSharedPreferenceChangeListener() {
                @Override
                public void onSharedPreferenceChanged(
                        SharedPreferences sharedPreferences, String key) {
                    switch (key){
                        case FISH:
                            fishSwitch = sharedPreferences.getBoolean(FISH,false);
                            createSearchCriteria(searchCriteria);
                            refineDishesList();
                            myAppAdapter.notifyDataSetChanged();
                            preferenceChanged = true;
                            break;
                        case MEAT:
                            meatSwitch = sharedPreferences.getBoolean(MEAT,false);
                            createSearchCriteria(searchCriteria);
                            refineDishesList();
                            myAppAdapter.notifyDataSetChanged();
                            preferenceChanged = true;
                            break;
                        case VEGETARIAN:
                            vegetarianSwitch = sharedPreferences.getBoolean(VEGETARIAN,false);
                            createSearchCriteria(searchCriteria);
                            refineDishesList();
                            myAppAdapter.notifyDataSetChanged();
                            preferenceChanged = true;
                            break;
                        case PIZZA:
                            pizzaSwitch = sharedPreferences.getBoolean(PIZZA,false);
                            createSearchCriteria(searchCriteria);
                            refineDishesList();
                            myAppAdapter.notifyDataSetChanged();
                            preferenceChanged = true;
                            break;
                        case PASTA:
                            pastaSwitch = sharedPreferences.getBoolean(PASTA,false);
                            createSearchCriteria(searchCriteria);
                            refineDishesList();
                            myAppAdapter.notifyDataSetChanged();
                            preferenceChanged = true;
                            break;
                        case RESTAURANTS:
                            restaurantSwitch = sharedPreferences.getBoolean(RESTAURANTS,false);
                            createSearchCriteria(searchCriteria);
                            refineDishesList();
                            myAppAdapter.notifyDataSetChanged();
                            preferenceChanged = true;
                            break;
                        case TAKEAWAY:
                            takeAwaySwitch = sharedPreferences.getBoolean(TAKEAWAY,false);
                            createSearchCriteria(searchCriteria);
                            refineDishesList();
                            myAppAdapter.notifyDataSetChanged();
                            preferenceChanged = true;
                            break;

                    } //end of switch statement
        }
    };

}

问题是我更换了一些开关后,适配器没有正确更新,仍然显示最后加载的“卡”。

如果refineList是空的(例如,有mo对象要显示),那么一切正常。

我阅读了很多关于我的问题的帖子,但他们说到处都知道notifyDataSetChanged()应该更新视图。

我在适配器中编写了一个方法来更新与适配器相关的列表,但即使我使用它,也没有任何反应。

有什么建议我做错了吗?

如果需要,我可以发布我正在使用的库的SwipeFlingAdapterView类的代码。

更新

我忘了提到我尝试从SetingsActivity两种方式返回MainActivity - &gt;使用SettingsActivity的“向上”按钮(父级为MainActivity)和Android设备的硬件后退按钮。

1.如果我使用UP按钮,一切都很完美,我想要它,但Logcat告诉我,返回它会破坏当前的MainActivity并创建一个新的,因此我的适配器重新启动,我不认为这非常有效。

2.如果我使用设备上的后退按钮,当我回到MainActivity时,它会调用onRestart()方法并且不会更新顶视图。我刷卡后会进行一些更新,但绝对不是我想要的,我完全卡住了。

事实证明,库中有一个错误,当你调用notifyDataSetChanged()时,当你使用SwipeFlingAdapterView时,控件不会进入getView()。如果你使用普通的ListView,它可以正常工作。所以我只需要调用flingContainer.removeAllViewsInLayout();在调用notifyDataSetChanged()之前并且运行良好。

1 个答案:

答案 0 :(得分:0)

只需快速查看代码,这部分代码是否正确?

@Override
public Object getItem(int position) {
    return position;
}

为什么不将其改为

@Override
public Object getItem(int position) {
    return dishesList.get(position);
}

稍后会检查出来