我有一个ListFragment
,有一个简单的ListView。当WebSocket上有新消息时,我会动态地向此ListView
添加新项。我将新行添加到ArrayAdapter
的开头,添加新项目时会有一个简单的动画。
问题是,当动画正在进行时,我正在尝试滚动,只有当我快速滚动时,旧版项目才会在ListView
上设置动画。
以下是ListAdapter
:
package adapters;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import custom_view.CompassView;
import hu.horadiz.ehoghu.blitzinfo.R;
import logger.AndroidLogger;
import model.BlitzLive;
/**
* Created by ehog on 2014.08.13..
*/
public class LiveArrayAdapter extends ArrayAdapter<BlitzLive> {
private ArrayList<BlitzLive> mLiveData;
private Context mContext;
private String[] mCompass;
private Integer mRecentAddedIndex;
private BlitzLive mRecentAdded;
private boolean mRecentAnimated;
private final static DateFormat DATE_FORMAT = new SimpleDateFormat("HH:MM:SS");
public LiveArrayAdapter(Context context, ArrayList<BlitzLive> mLiveData) {
super(context, 0, mLiveData);
this.mLiveData = mLiveData;
this.mContext = context;
mCompass = mContext.getResources().getStringArray(R.array.compass);
}
@Override
public synchronized void add(BlitzLive object) {
mLiveData.add(0,object);
if (mLiveData.size() > 120)
{
mLiveData.remove(mLiveData.size()-1);
}
mRecentAddedIndex = 0;
mRecentAnimated = true;
mRecentAdded = object;
notifyDataSetChanged();
}
private String coords(Double lat, Double lng)
{
String latitude_text = lat >= 0 ? mCompass[0] : mCompass[8];
String longitude_text = lng >= 0 ? mCompass[4] : mCompass[12];
DecimalFormat nf = new DecimalFormat();
DecimalFormatSymbols p=new DecimalFormatSymbols();
p.setDecimalSeparator('.');
nf.setDecimalFormatSymbols(p);
nf.setMaximumFractionDigits(3);
nf.setMinimumFractionDigits(3);
return String.format("%s %s, %s %s",nf.format(lat),latitude_text,nf.format(lng),longitude_text);
}
@Override
public int getCount() {
return mLiveData.size();
}
@Override
public synchronized View getView(int i, View view, ViewGroup viewGroup) {
if (view == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.holder_blitzes_live, null);
}
TextView settlem = (TextView)view.findViewById(R.id.live_settlem);
TextView data = (TextView)view.findViewById(R.id.live_data);
TextView distancemarker = (TextView)view.findViewById(R.id.live_distancemarker);
DecimalFormat nf = new DecimalFormat();
DecimalFormatSymbols p=new DecimalFormatSymbols();
p.setDecimalSeparator('.');
nf.setDecimalFormatSymbols(p);
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
if (!mLiveData.get(i).Settlement.equals(""))
{
settlem.setText(mLiveData.get(i).Settlement);
data.setText(String.format("%s km, %s (%s)", nf.format(mLiveData.get(i).Distance), mCompass[(int)((((mLiveData.get(i).Bearing + 11.0) / 22.5) % 16))],coords(mLiveData.get(i).Latitude,mLiveData.get(i).Longitude)));
}
else
{
settlem.setText(coords(mLiveData.get(i).Latitude,mLiveData.get(i).Longitude));
data.setText(String.format("%s km, %s", nf.format(mLiveData.get(i).Distance), mCompass[(int)((((mLiveData.get(i).Bearing + 11.0) / 22.5) % 16))]));
}
CompassView compass = (CompassView)view.findViewById(R.id.live_compass);
compass.setBaseBearing(new Float(mLiveData.get(i).Bearing));
ImageView flag = (ImageView)view.findViewById(R.id.live_flag);
if (mLiveData.get(i).CountryCode.equals("--"))
{
flag.setImageResource(mContext.getResources().getIdentifier(String.format("_cf_big_%s","empty"), "drawable", "hu.horadiz.ehoghu.blitzinfo"));
}
else
{
flag.setImageResource(mContext.getResources().getIdentifier(String.format("_cf_big_%s", mLiveData.get(i).CountryCode), "drawable", "hu.horadiz.ehoghu.blitzinfo"));
}
if (mLiveData.get(i).Distance >= 1000.0)
{
distancemarker.setBackgroundResource(R.drawable.groupedblitzes_count_background_1000plus);
}
else if (mLiveData.get(i).Distance >= 200.0 && mLiveData.get(i).Distance < 1000.0)
{
distancemarker.setBackgroundResource(R.drawable.groupedblitzes_count_background_200plus);
}
else if (mLiveData.get(i).Distance >= 50.0 && mLiveData.get(i).Distance < 200.0)
{
distancemarker.setBackgroundResource(R.drawable.groupedblitzes_count_background_50plus);
}
else if (mLiveData.get(i).Distance >= 20.0 && mLiveData.get(i).Distance < 50.0)
{
distancemarker.setBackgroundResource(R.drawable.groupedblitzes_count_background_20plus);
}
else if (mLiveData.get(i).Distance >= 5.0 && mLiveData.get(i).Distance < 20.0)
{
distancemarker.setBackgroundResource(R.drawable.groupedblitzes_count_background_5plus);
}
else if (mLiveData.get(i).Distance >= 0.0 && mLiveData.get(i).Distance < 5.0)
{
distancemarker.setBackgroundResource(R.drawable.groupedblitzes_count_background_0plus);
}
//This if is false when the wrong item is animates, but the animation is still occurs
if (mRecentAddedIndex == i && mRecentAnimated && mRecentAdded.equals(mLiveData.get(i)))
{
mRecentAnimated = false;
Animation ANIM_APPEAR = AnimationUtils.loadAnimation(getContext(), R.anim.push_right_in);
ANIM_APPEAR.setDuration(500);
view.findViewById(R.id.live_holder_parent).startAnimation(ANIM_APPEAR);
AndroidLogger.PushDebugMessage("Animáció megtörtént: "+mRecentAddedIndex+" "+mLiveData.get(i).Settlement);
}
return view;
}
}
和ListFragment
:
package fragments;
import android.app.Fragment;
import android.app.ListFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import org.json.JSONObject;
import java.util.ArrayList;
import adapters.LiveArrayAdapter;
import hu.horadiz.ehoghu.blitzinfo.R;
import logger.AndroidLogger;
import model.BlitzLive;
import using_net.BlitzLiveDataAsyncTask;
/**
* Created by ehog on 2014.08.12..
*/
public class LiveDataFragment extends ListFragment implements BlitzLiveDataAsyncTask.OnMessage
{
private BlitzLiveDataAsyncTask _mLiveAsyncTask;
private LiveArrayAdapter mListAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.fragment_live, container, false);
return v;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
setHasOptionsMenu(true);
super.onCreate(savedInstanceState);
mListAdapter = new LiveArrayAdapter(getActivity(),new ArrayList<BlitzLive>());
mListAdapter.setNotifyOnChange(true);
setListAdapter(mListAdapter);
}
@Override
public void onStart()
{
if (getActivity() != null)
{
getActivity().setTitle(getActivity().getResources().getString(R.string.title_liveview));
}
super.onStart();
if (_mLiveAsyncTask != null)
{
_mLiveAsyncTask.cancel(true);
}
_mLiveAsyncTask = new BlitzLiveDataAsyncTask(this);
_mLiveAsyncTask.execute();
}
@Override
public void onPause() {
super.onPause();
if (_mLiveAsyncTask != null)
{
_mLiveAsyncTask.stop();
_mLiveAsyncTask.cancel(true);
AndroidLogger.PushDebugMessage("onPause cancel");
}
}
@Override
public void onCreateOptionsMenu (Menu menu, MenuInflater inflater)
{
menu.clear();
inflater.inflate(R.menu.blitz_live, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public void onMessage(final JSONObject message)
{
getActivity().runOnUiThread(new Runnable() {
public void run() {
((LiveArrayAdapter)getListAdapter()).add(BlitzLive.fromJSON(message));
}
});
AndroidLogger.PushDebugMessage(String.format("Websocket message: %s", message.toString()));
}
}
答案 0 :(得分:0)
是回收是问题所在。在适配器中添加动画时,必须放置一个&#34;删除动画代码&#34;:
if (mRecentAddedIndex == i && mRecentAnimated && mRecentAdded.equals(mLiveData.get(i)))
{
mRecentAnimated = false;
Animation ANIM_APPEAR = AnimationUtils.loadAnimation(getContext(), R.anim.push_right_in);
ANIM_APPEAR.setDuration(500);
view.findViewById(R.id.live_holder_parent).startAnimation(ANIM_APPEAR);
AndroidLogger.PushDebugMessage("Animáció megtörtént: "+mRecentAddedIndex+" "+mLiveData.get(i).Settlement);
} else {
// remove animation
答案 1 :(得分:0)
最终代码:(清理,动画最后等等)
if (mRecentAddedIndex == i && mRecentAnimated && mRecentAdded.equals(mLiveData.get(i)))
{
mRecentAnimated = false;
layout.startAnimation(ANIM_APPEAR);
AndroidLogger.PushDebugMessage("Animáció megtörtént (Animation occurred): "+mRecentAddedIndex+" "+mLiveData.get(i).Settlement);
}
else
{
layout.clearAnimation();
}