自定义listview android中的textview不稳定
Posted
技术标签:
【中文标题】自定义listview android中的textview不稳定【英文标题】:The textview is not stable in custom listview android 【发布时间】:2019-02-24 07:02:30 【问题描述】:实际上我有一个包含倒数计时器的自定义列表视图,倒数计时器是由处理程序创建的,现在列表加载正常,一切似乎都是正确的,但是当我开始滚动倒数计时器时,值变得不稳定且不稳定似乎彼此重叠意味着 lastrow 值打印在第一行中,诸如此类的值是向上和向下的,并且它不能正常工作,这里 API 发送一个 long 值,该值传递给处理程序,处理程序将其转换到倒数计时器,所以问题出在哪里,每当我刷新列表时一切都很好,但是当我开始滚动时,同样的问题又来了..这是我的代码
public class fixtures extends Fragment
private ListView fixtureListView;
String Balance,userEmail;
SwipeRefreshLayout mSwipeRefreshLayout;
private static final String FORMAT = "%02d:%02d:%02d";
List<ListView_fixture_conveyer> fixture_conveyerList;
ListView_fixture_conveyer fixtureList;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState)
View view = inflater.inflate(R.layout.fixtures, viewGroup, false);
fixtureListView = view.findViewById(R.id.fixture_list);
mSwipeRefreshLayout = view.findViewById(R.id.swipeToRefresh);
User user = SharedPrefManager.getInstance(getActivity()).getUser();
userEmail= user.getEmail();
new JSONTask().execute("http://www.judgement6.com/judgement_files/fixture_json.php");
DisplayImageOptions options = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(Objects.requireNonNull(getActivity()))
.defaultDisplayImageOptions(options)
.build();
com.nostra13.universalimageloader.core.ImageLoader.getInstance().init(config);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener()
@Override
public void onRefresh()
fixture_conveyerList.clear();
new JSONTask().execute("http://www.judgement6.com/judgement_files/fixture_json.php");
mSwipeRefreshLayout.setRefreshing(false);
);
return view;
@SuppressLint("StaticFieldLeak")
public class JSONTask extends AsyncTask<String, String, List<ListView_fixture_conveyer>>
ProgressDialog loading;
@Override
protected void onPreExecute()
super.onPreExecute();
loading = ProgressDialog.show(getActivity(), "loading,please wait...", null, true, true);
@Override
protected List<ListView_fixture_conveyer> doInBackground(String... params)
HttpURLConnection connection = null;
BufferedReader reader = null;
try
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuilder buffer = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null)
buffer.append(line);
String finalJson = buffer.toString();
JSONObject parentObject = new JSONObject(finalJson);
JSONArray parentArray = parentObject.getJSONArray("list");
fixture_conveyerList = new ArrayList<ListView_fixture_conveyer>();
for (int i = 0; i < parentArray.length(); i++)
JSONObject finalObject = parentArray.getJSONObject(i);
Log.e("fixtureObject",finalObject.toString());
fixtureList = new ListView_fixture_conveyer();
fixtureList.setTournament(finalObject.getString("tournament"));
fixtureList.setTeam1_photo(finalObject.getString("team1_photo"));
fixtureList.setTeam2_photo(finalObject.getString("team2_photo"));
fixtureList.setTeam1_name(finalObject.getString("team1_name"));
fixtureList.setTeam2_name(finalObject.getString("team2_name"));
fixtureList.setTime(finalObject.getString("Time"));
fixture_conveyerList.add(fixtureList);
return fixture_conveyerList;
catch (IOException | JSONException e)
e.printStackTrace();
finally
if (connection != null)
connection.disconnect();
try
if (reader != null)
reader.close();
catch (IOException e)
e.printStackTrace();
return null;
@Override
protected void onPostExecute(List<ListView_fixture_conveyer> result)
super.onPostExecute(result);
if (result !=null)
loading.dismiss();
ListAdapter adapter = new ListAdapter(getActivity(), R.layout.custom_list_fixture, result);
fixtureListView.setAdapter(adapter);
else
Toast.makeText(getActivity(), "No Internet Connection!", Toast.LENGTH_LONG).show();
loading.dismiss();
public class ListAdapter extends ArrayAdapter
private List<ListView_fixture_conveyer> fixture_conveyerList;
private int resource;
private LayoutInflater inflater;
ListAdapter(Context context, int resource, List<ListView_fixture_conveyer> objects)
super(context, resource, objects);
fixture_conveyerList = objects;
this.resource = resource;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@Override
public int getViewTypeCount()
return getCount();
@Override
public int getItemViewType(int position)
return position;
@NonNull
@Override
public View getView(final int position, View convertView, @NonNull ViewGroup parent)
if (convertView == null)
convertView = inflater.inflate(resource, null);
final TextView team1_name,team2_name;
final TextView tournament,time;
ImageView team1_photo,team2_photo;
team1_photo = convertView.findViewById(R.id.team1);
team2_photo = convertView.findViewById(R.id.team2);
team1_name = convertView.findViewById(R.id.team1_name);
team2_name = convertView.findViewById(R.id.team2_name);
tournament= convertView.findViewById(R.id.tournament);
time= convertView.findViewById(R.id.timecounter);
ImageLoader.getInstance().displayImage(fixture_conveyerList.get(position).getTeam1_photo(), team1_photo);
ImageLoader.getInstance().displayImage(fixture_conveyerList.get(position).getTeam2_photo(), team2_photo);
team1_name.setText(fixture_conveyerList.get(position).getTeam1_name());
team2_name.setText(fixture_conveyerList.get(position).getTeam2_name());
tournament.setText(fixture_conveyerList.get(position).getTournament());
time.setText(fixture_conveyerList.get(position).getTime());
Log.e("mytimer",fixture_conveyerList.get(position).getTime());
if (!("false").equals(fixture_conveyerList.get(position).getTime()))
Log.e("inside_mytimer",fixture_conveyerList.get(position).getTime());
long newValue=Long.parseLong(fixture_conveyerList.get(position).getTime());
new CountDownTimer(newValue, 1000)
@SuppressLint("DefaultLocale", "SetTextI18n")
public void onTick(long millisUntilFinished)
time.setText("" + String.format(FORMAT,
TimeUnit.MILLISECONDS.toHours(millisUntilFinished),
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) - TimeUnit.HOURS.toMinutes(
TimeUnit.MILLISECONDS.toHours(millisUntilFinished)),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished))));
public void onFinish()
time.setText("Fixture closed");
.start();
else
time.setText("Fixture closed");
return convertView;
这是我的模型类代码
public class ListView_fixture_conveyer
private String tournament;
private String team1_photo;
private String team2_photo;
private String team1_name;
private String team2_name;
private String time;
public String getTime()
return time;
public void setTime(String time)
this.time = time;
public String getTeam1_name()
return team1_name;
public void setTeam1_name(String team1_name)
this.team1_name = team1_name;
public String getTeam2_name()
return team2_name;
public void setTeam2_name(String team2_name)
this.team2_name = team2_name;
public String getTournament()
return tournament;
public void setTournament(String tournament)
this.tournament = tournament;
public String getTeam1_photo()
return team1_photo;
public void setTeam1_photo(String team1_photo)
this.team1_photo = team1_photo;
public String getTeam2_photo()
return team2_photo;
public void setTeam2_photo(String team2_photo)
this.team2_photo = team2_photo;
【问题讨论】:
最好使用 RecylerView 好的,但是现在请帮我解决这个问题,因为我无法在这个项目中更改它 使用持有人模式。 我怎么没用过这个 【参考方案1】:编辑 (已测试)
---> 对于 Timer 问题,您需要在类中获取 time 变量并更新变量 with Handler 将其与重新加载数据一起使用。喜欢,
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable()
@Override
public void run()
for (int i = 0, dataLength = fixture_conveyerList.size(); i < dataLength; i++)
ListView_fixture_conveyer item = fixture_conveyerList.get(i);
item.timeRemaining -= 1000;
adapter.notifyDataSetChanged();
timerHandler.postDelayed(this, 1000); //run every Second
;
列出适配器类
public class ListAdapter extends ArrayAdapter
private List<ListView_fixture_conveyer> fixture_conveyerList;
private int resource;
private LayoutInflater inflater;
ViewHolder holder;
ListAdapter(Context context, int resource, List<ListView_fixture_conveyer> objects)
super(context, resource, objects);
fixture_conveyerList = objects;
this.resource = resource;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
timerHandler.postDelayed(timerRunnable, 50); //start unique timer
@Override
public int getViewTypeCount()
return getCount();
@Override
public int getItemViewType(int position)
return position;
@NonNull
@Override
public View getView(final int position, View convertView, @NonNull ViewGroup parent)
if (convertView == null)
convertView = inflater.inflate(resource, null);
holder = new ViewHolder();
holder.team1_photo = convertView.findViewById(R.id.team1);
holder.team2_photo = convertView.findViewById(R.id.team2);
holder.team1_name = convertView.findViewById(R.id.team1_name);
holder.team2_name = convertView.findViewById(R.id.team2_name);
holder.tournament = convertView.findViewById(R.id.tournament);
holder.time = convertView.findViewById(R.id.timecounter);
convertView.setTag(holder);
else
holder = (ViewHolder) convertView.getTag();
ImageLoader.getInstance().displayImage(fixture_conveyerList.get(position).getTeam1_photo(), holder.team1_photo);
ImageLoader.getInstance().displayImage(fixture_conveyerList.get(position).getTeam2_photo(), holder.team2_photo);
holder.team1_name.setText(fixture_conveyerList.get(position).getTeam1_name());
holder.team2_name.setText(fixture_conveyerList.get(position).getTeam2_name());
holder.tournament.setText(fixture_conveyerList.get(position).getTournament());
holder.time.setText(fixture_conveyerList.get(position).timeRemaining);
Log.e("mytimer", fixture_conveyerList.get(position).getTime());
if (!("false").equals(fixture_conveyerList.get(position).getTime()))
Log.e("inside_mytimer", fixture_conveyerList.get(position).getTime());
long newValue = fixture_conveyerList.get(position).timeRemaining;
if (newValue > 0)
holder.time.setText(String.format(FORMAT,
TimeUnit.MILLISECONDS.toHours(newValue),
TimeUnit.MILLISECONDS.toMinutes(newValue) - TimeUnit.HOURS.toMinutes(
TimeUnit.MILLISECONDS.toHours(newValue)),
TimeUnit.MILLISECONDS.toSeconds(newValue) - TimeUnit.MINUTES.toSeconds(
TimeUnit.MILLISECONDS.toMinutes(newValue))));
else
holder.time.setText("Fixture closed");
else
holder.time.setText("Fixture closed");
return convertView;
【讨论】:
除最后一个之外的所有计时器都消失了,它只打印来自 API 本身的原始值,当我滚动列表时最后一个也会抖动 你在哪里定义timeRemaining?? 我在哪里添加那个可以制作计时器的处理程序??@Abhay Koradiya 我需要在我的模型类中添加它吗?你能检查我的模型类并具体告诉我。 怎么样,我的意思是准确的以上是关于自定义listview android中的textview不稳定的主要内容,如果未能解决你的问题,请参考以下文章
android下拉刷新和滑动到底部加载更多,自定义listview
Android - ListView 中的 EditTexts 绑定到自定义 ArrayAdapter - 跟踪更改
ArrayIndexOutOfBoundsException 与 ListView 中的多个视图的自定义 Android 适配器
将自定义 ListView 项传递给 Android 中的其他活动