我是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()之前并且运行良好。
答案 0 :(得分:0)
只需快速查看代码,这部分代码是否正确?
@Override
public Object getItem(int position) {
return position;
}
为什么不将其改为
@Override
public Object getItem(int position) {
return dishesList.get(position);
}
稍后会检查出来