简体   繁体   English

Android列表视图当前位置无法正常工作

[英]Android list view current position doesn't work properly

I'm Getting data from my database and pushing them into ListView to view all the data. 我正在从数据库中获取数据,并将其推入ListView中以查看所有数据。

Inside my ListView I also have a TextView with the text "Like" in it. 在我的ListView中,我还有一个TextView,其中包含文本“ Like”。 Now when I click the like text it will change to "Liked" and I'm updating my like status in my database. 现在,当我单击“喜欢”文本时,它将变为“喜欢”,并且我正在更新数据库中的喜欢状态。

Now my problem is that when i click the "Like" text, the text changes to "Liked" and also it is updated in DB. 现在我的问题是,当我单击“喜欢”文本时,该文本更改为“喜欢”,并且也在DB中进行了更新。 But also when I scroll through the List View, I can notice other lists' Like text is also changed to Liked. 而且,当我滚动浏览“列表视图”时,我可以注意到其他列表的“赞”文本也更改为“喜欢”。 I'm not sure what's going wrong. 我不知道怎么了。

I've been trying to get around this problem for quite some days but had no success. 我已经尝试解决这个问题好几天了,但是没有成功。

This is my adapter code. 这是我的适配器代码。 At the bottom you can see my onClickListener for the textview 在底部,您可以看到我的onClickListener文本视图

package com.mytestapp.myapp;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class ForumAdapter extends ArrayAdapter<DiscussionList> {
    private static List<DiscussionList> items = null;

    public ForumAdapter(Context context, List<DiscussionList> items) {
        super(context, R.layout.custom_list, items);
        this.items = items;
    }

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

    public static DiscussionList getModelPosition(int position) {
        return items.get(position);
    }

    public void refill(List<DiscussionList> items) {
        items.clear();
        items.addAll(items);
        notifyDataSetChanged();
    }

    public static class ViewHolder {
        WebView mywebviewholder;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        View v = convertView;

        if (v == null) {
            LayoutInflater li = LayoutInflater.from(getContext());
            v = li.inflate(R.layout.custom_list, null);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        DiscussionList app = items.get(position);

        if (app != null) {
            TextView titleText = (TextView) v.findViewById(R.id.dscTitle);
            TextView categoryText = (TextView) v.findViewById(R.id.dscCategory);
            TextView descriptionText = (TextView) v
                    .findViewById(R.id.dscDescription);
            TextView timeText = (TextView) v.findViewById(R.id.dscTime);
            TextView idText = (TextView) v.findViewById(R.id.dscDiscId);
            final TextView likeText = (TextView) v.findViewById(R.id.likeText1);
            String like_Status = app.getLikeStatus();

            titleText.setText(app.getTitle());
            categoryText.setText(app.getCategory());
            descriptionText.setText(app.getDescription());
            timeText.setText(app.getTime());
            idText.setText(app.getDiscId());
            if (like_Status == "null") {
                likeText.setText("Like");
            } else {
                likeText.setText("Liked");
            }

            final String dId = app.getDiscId();

            // onClick for image button inside list view

            likeText.setTag(new Integer(position));
            likeText.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    final Integer myposition = (Integer) view.getTag();
                    // Toast.makeText(getContext(), "" + dId,
                    // Toast.LENGTH_SHORT)
                    // .show();
                    likeText.setText("Liked");
                    MainActivity val = new MainActivity();
                    val.updateLikeTable(dId);
                }

            });

        }

        return v;
    }
}

And also this is my MainActivity.java file where i update the likes in database 这也是我的MainActivity.java文件,我在其中更新数据库中的赞

package com.mytestapp.myapp;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends ListActivity implements FetchDataListener {
    public static String strTitle = "0", strCategory = "0",
            strDescription = "0", strTime = "0", strDid = "0";
    Collegemate_DB db = new Collegemate_DB(this);
    int likeStatus = 1;
    private ProgressDialog dialog;
    public static String usId=null;
    ImageButton imgButton;
    List<DiscussionList> items = new ArrayList<DiscussionList>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list_forum_topics);
        usId = db.getCurrentuserId();
        initView();

        if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
                    .permitAll().build();
            StrictMode.setThreadPolicy(policy);
        }
        /*
         * On click listener to get values from DiscussionList class and send it
         * to another activity when clicking on the list item
         */

        ListView forumList = getListView();
        forumList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                // Get position of the clicked list item from adapter

                String dTitle, dCategory, dDescription, dTime, dDid;

                DiscussionList accessVar = ForumAdapter
                        .getModelPosition(position);
                dTitle = accessVar.getTitle();
                dCategory = accessVar.getCategory();
                dDescription = accessVar.getDescription();
                dTime = accessVar.getTime();
                dDid = accessVar.getDiscId();

                /*
                 * Storing the forum values in string and passing it to another
                 * activity
                 */

                String values[] = { dTitle, dCategory, dDescription, dTime,
                        dDid };
                Intent i = new Intent(MainActivity.this, ForumFullView.class);
                i.putExtra("sendData", values);
                startActivity(i);
            }
        });
    }

    private void initView() {
        // show progress dialog
        Log.i("j","Inside Init");
        dialog = ProgressDialog.show(this, "", "Loading...");

        String url = "http://example.com/mypath/listData.php?currentUser_id="
                + usId;
        Log.i("Fetch Url : ", url);
        FetchDataTask task = new FetchDataTask(this);
        task.execute(url);
    }

    @Override
    public void onFetchComplete(List<DiscussionList> data) {
        // dismiss the progress dialog
        if (dialog != null)
            dialog.dismiss();
        // create new adapter
        ListView forumList = getListView();
        // set the adapter to list
        ForumAdapter adapter = new ForumAdapter(this, data);
        if (forumList.getAdapter() == null) {
            //final ForumAdapter adapter = new ForumAdapter(this, data);
            forumList.setAdapter(adapter);
        } else {
            ((ForumAdapter) forumList.getAdapter()).refill(items);
        }
        // setListAdapter(adapter);
    }

    @Override
    public void onFetchFailure(String msg) {
        // dismiss the progress dialog
        if (dialog != null)
            dialog.dismiss();
        // show failure message
        Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
    }

    public void updateLikeTable(String dId,List<DiscussionList> items) {
        try {
            String likeUrl = "http://example.com/mypath/createlike.php?discId="
                    + dId + "&userId=" + usId + "&like_status=" + likeStatus;
            HttpClient client = new DefaultHttpClient();
            HttpGet request = new HttpGet();
            request.setURI(new URI(likeUrl));
            client.execute(request);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Any help is appreciated. 任何帮助表示赞赏。

Thanks in advance 提前致谢

The problem you're having is that the ListView widget recycles its views if it can. 您遇到的问题是ListView小部件会回收其视图(如果可以的话)。 Once a view is off the screen from scrolling, it goes onto a garbage heap so that when a new view scrolls into place it can be reused, rather than requiring a fresh one to be inflated from scratch. 一旦视图离开屏幕,它就会进入垃圾堆,以便在新视图滚动到位时可以重用,而无需从头开始填充一个新视图。 That recycled view is the convertView parameter in the getView() method. 该回收视图是getView()方法中的convertView参数。 When your ListView is first populating, convertView will always be null, since the garbage pile has nothing in it, so you're forced to inflate new views, but subsequent calls will likely have that parameter as non-null. 首次填充ListView ,由于垃圾堆中没有任何内容,所以convertView始终为null,因此您不得不强制填充新视图,但是后续调用可能会将该参数设置为非null。

The practical result of this is that when a clicked view that's been set to "Liked" gets recycled, the TextView is still there and still populated with "Liked" rather than the presumed default of "Like". 实际的结果是,当设置为“喜欢”的单击视图被回收时, TextView仍然存在,并且仍填充有“喜欢”而不是假定的默认值“喜欢”。 So if you click a view, then scroll down so it goes off the screen, it'll come back around and cause the bug you're seeing. 因此,如果您单击一个视图,然后向下滚动使其离开屏幕,它将重新出现并导致您看到的错误。

What you'll probably want to do to fix this is to set the text of likeText within getView() every time, based on what it is in your database. 要解决此问题,您可能需要每次基于数据库中的likeTextgetView()设置likeText的文本。 If the post has been liked, set it to "Liked", and if it hasn't, set it to "Like". 如果帖子已被顶过,则将其设置为“喜欢”,否则将其设置为“喜欢”。 It should just be one more line, assuming you have easy access to whether or not the post is liked from your DiscussionList object. 假设您可以轻松地从DiscussionList对象访问帖子是否被喜欢,那么它应该只是一行。

PS As a side note, hard-coded strings are typically frowned upon in Android, so you may want to move your "Liked" string into the resource files. PS附带说明,在Android中通常不赞成使用硬编码字符串,因此您可能需要将“喜欢”字符串移动到资源文件中。 It's not really necessary unless you're planning to do translations, but it's still good practice. 除非您计划进行翻译,否则这不是真正必要的,但这仍然是一种好习惯。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM