2

我正在使用 Json 数据创建一个列表视图。我正在填充一些图像、文本字段和一个按钮。当用户单击按钮时,按钮标题会发生变化。

问题是如果按钮被修改并且用户滚动列表视图按钮重置为第一个状态。请查看此视频,最好解释一下:https ://www.youtube.com/watch?v=57ZraP7ED2E&feature=youtu.be

适配器

public class FilmRequestAdapter extends ArrayAdapter<FilmRequest>{
    Context context;
    List<FilmRequest> data;

    public FilmRequestAdapter(Context context, int resource, List<FilmRequest> objects) {
        super(context, resource, objects);
        // TODO Auto-generated constructor stub

        this.context=context;
        this.data=objects;
    }

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

        if (row==null) {
            LayoutInflater inflater=((Activity)context).getLayoutInflater();
            row=inflater.inflate(R.layout.film_request_list,null);
        }

        ((TextView)row.findViewById(R.id.FilmRequestFilmTitle)).setText(((FilmRequest)data.get(position)).title);
        ((TextView)row.findViewById(R.id.FilmRequestRating)).setText("Imdb Puanı : "+((FilmRequest)data.get(position)).rating);
        ((TextView)row.findViewById(R.id.FilmRequestOrder)).setText("Sıra : "+((FilmRequest)data.get(position)).order);
        ((TextView)row.findViewById(R.id.FilmRequestVoteCount)).setText("Oya adeti : "+((FilmRequest)data.get(position)).voteCount);

        Button button=(Button)row.findViewById(R.id.FilmRequestActionButton);
        String status=((FilmRequest)data.get(position)).status;
        boolean requested=((FilmRequest)data.get(position)).requested;
        boolean voted=((FilmRequest)data.get(position)).voted;
        if (status.equalsIgnoreCase("A") || status.equalsIgnoreCase("")) {

            if (requested) {
                if (voted) {
                    button.setText("Oylanmış");
                    button.setEnabled(false);
                }else {
                    button.setText("+ Oyla");
                    button.setEnabled(true);
                    button.setTag(R.string.film_request_action, "VOTEABLE");
                    button.setTag(R.string.film_request_id,((FilmRequest)data.get(position)).id);
                }
            } else {
                button.setText("Filmi İste");
                button.setEnabled(true);
                button.setTag(R.string.film_request_action, "REQUESTABLE");
                button.setTag(R.string.film_request_id,((FilmRequest)data.get(position)).imdbId);               
            }

        } else {
            button.setText("Eklenmiş");
            button.setEnabled(false);
        }

        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                FilmRequestActivity.ButtonClickFunction(context,(Button)v);
            }
        });

        ((ImageView)row.findViewById(R.id.FilmRequestPoster)).setImageBitmap(((FilmRequest)data.get(position)).bm);

        return row;

    }

}

异步类

public class FilmRequestAsync extends AsyncTask<String, Void, List<FilmRequest>>{

    Context context;
    ListView listView;
    private ProgressDialog progressDialog;

    public FilmRequestAsync (Context context) {
        this.context=context;
        this.listView=(ListView) ((Activity)context).findViewById(R.id.FilmRequestList);
    }

    protected void onPreExecute() {
        this.progressDialog = ProgressDialog.show(context, "Lütfen Bekleyin...", "Fimler Yükleniyor...",true);
    }   

    @Override
    protected List<FilmRequest> doInBackground(String... params) {
        Log.d("debug","FilmRequestAsync param[0]"+params[0]);
        List<FilmRequest> filmRequests=null;
        String jsonString;

        try {
            jsonString=GeneralFunctions.getUrl(params[0]);
            if (jsonString!=null) {

                 filmRequests=this.getFilmRequestListFromJsonString(jsonString);

            }
        }catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return filmRequests;        


    }

    private List<FilmRequest> getFilmRequestListFromJsonString(String jsonString){
        List<FilmRequest> filmRequests=new ArrayList<FilmRequest>();
        try {
            Log.d("debug","Json Verisi oluşturuluyor.");
            JSONArray json=new JSONArray(jsonString);
            Log.d("debug","Json Verisi Oluşturuldu");

            int i;
            for (i=0;i<json.length();i++) {
                JSONObject tmpJson=(JSONObject)json.get(i);
                filmRequests.add(
                    new FilmRequest(
                            tmpJson.getString("id"),
                            tmpJson.getString("imdb_id"),
                            tmpJson.getString("poster"),
                            tmpJson.getString("title"),
                            tmpJson.getString("rating"),
                            tmpJson.getString("order"),
                            tmpJson.getString("status"),
                            tmpJson.getString("vote_count"),
                            tmpJson.getBoolean("requested"),
                            tmpJson.getBoolean("voted")
                            )
                );
                tmpJson=null;
            }

        } catch (JSONException e) {
            Log.d("debug","Json Verisi HATASI:");

            filmRequests=null;
            e.printStackTrace();
        }

        return filmRequests;        
    }

    @Override
    protected void onPostExecute(List<FilmRequest> result) {
            this.progressDialog.dismiss();
            if (result==null) return;

            // TODO Auto-generated method stub
            super.onPostExecute(result);
            Log.d("debug", "FilmRequestAsync onPostExecute Başı");

            FilmRequestAdapter filmRequestAdapter=new FilmRequestAdapter(context, R.layout.film_request_list, result);
            Log.d("debug","FilmRequestAsync:Adapter set ediliyor.");
            listView.setAdapter(filmRequestAdapter);
            Log.d("debug", "onPostExecute Sonu");
        }
}

列出 XML 文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/film_container"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="2dp"
    android:background="@drawable/film_list_style"
    android:orientation="horizontal"
    android:padding="3dp" >

    <!--  ListRow Left sied Thumbnail image -->

    <!-- Title Of Song-->

    <!-- Artist Name -->

    <!-- Rightend Duration -->

    <ImageView
        android:id="@+id/FilmRequestPoster"
        android:layout_width="83dp"
        android:layout_height="106dp" />

    <Button
        android:id="@+id/FilmRequestActionButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:text="+ Oyla" />

    <TextView
        android:id="@+id/FilmRequestRating"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/FilmRequestFilmTitle"
        android:layout_below="@+id/FilmRequestFilmTitle"
        android:text="Rating" />

    <TextView
        android:id="@+id/FilmRequestVoteCount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/FilmRequestOrder"
        android:layout_below="@+id/FilmRequestOrder"
        android:text="VoteCount" />

    <TextView
        android:id="@+id/FilmRequestFilmTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/FilmRequestActionButton"
        android:layout_toRightOf="@+id/FilmRequestPoster"
        android:text="Rihanna Love the way lie"
        android:textColor="#040404"
        android:textSize="15dip"
        android:textStyle="bold"
        android:typeface="sans" />

    <TextView
        android:id="@+id/FilmRequestOrder"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/FilmRequestRating"
        android:layout_toRightOf="@+id/FilmRequestPoster"
        android:text="Order" />

</RelativeLayout>

点击功能

    public static void ButtonClickFunction(Context context, Button button){
        //Burası Ne işlem yapabileceğimizi gösteriyor.
        //REQUESTABLE veya VOTABLE değerleri alabilir.
        String action=(String)button.getTag(R.string.film_request_action);
        String id=(String)button.getTag(R.string.film_request_id);

        Log.d("debug", "String action="+action);

        if (action.equalsIgnoreCase("VOTEABLE")) {
            VoteFilm(context, button,id);
        } else if (action.equalsIgnoreCase("REQUESTABLE")) {
            RequestFilm(context, button, id);
        }
    }   

    public static void VoteFilm(Context context, final Button button, final String id){
        final String callUrl=context.getString(R.string.api_url)+"?request=vote_film&user_id=1&id="+id;
        Log.d("debug", "FilmRequestActivity->VoteFilm->callUrl:"+callUrl);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    GeneralFunctions.getUrl(callUrl);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                button.post(new Runnable() {
                    @Override
                    public void run() {
                        button.setText("Oylanmış");
                        button.setEnabled(false);
                    }
                });
            }
        }).start();
        Toast.makeText(context, "Film Oylandı", Toast.LENGTH_SHORT).show(); 
    }

    public static void RequestFilm(Context context, final Button button,final String id){
        final String callUrl=context.getString(R.string.api_url)+"?request=request_film&user_id=1&id="+id;
        Log.d("debug", "FilmRequestActivity->RequestFilm->callUrl:"+callUrl);

        new Thread(new Runnable() {

            @Override
            public void run() {
                String jsonString;
                final JSONObject jsonObject;
                try {
                    jsonString = GeneralFunctions.getUrl(callUrl);
                    jsonObject=GeneralFunctions.StringToJSONObject(jsonString);
                    if (jsonObject!=null) {
                        button.post(new Runnable() {
                            @Override
                            public void run() {

                                try {
                                    Log.d("debug","Inside Thread");
                                    JSONObject data=(JSONObject) jsonObject.get("data");
                                    String new_id=data.getString("id");
                                    button.setTag(R.string.film_request_action,"VOTEABLE");
                                    button.setTag(R.string.film_request_id,new_id);
                                    button.setText("+Oyla");
                                    button.setEnabled(true);

                                } catch (JSONException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }

                            }
                        });

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

    }
}
4

4 回答 4

2

问题是您在调用时从不修改适配器的内容ButtonClickFunction。这样,当您滚动时,将满足保持状态并将旧字符串设置为您的按钮。我建议你更好地考虑你的设计。作为快速修复,您可以为您的 Button 设置另一个标签,在位置添加 FilmRequest 对象,例如:

    final FilmRequest filmRequest = (FilmRequest)data.get(position);
    String status = filmRequest.status;
    boolean requested = filmRequest.requested;
    boolean voted = filmRequest.voted;

然后,在里面ButtonClickFunction,检索这个标签并status相应地改变它

于 2013-07-25T12:13:38.113 回答
0

我是同样的问题,但我通过这段代码解决了

public class CustomizeListView extends ListActivity {

    LayoutInflater inflater;
    static int index = 0;

    // AutoCompleteTextView autoCompleteTextView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_order);
        inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item, arrayList_Category);
        dataAdapter
                .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        final CustomAdapter adapter = new CustomAdapter(this,
                R.layout.activity_orderitem, arrayListItems);
        setListAdapter(adapter);
    }

    private class CustomAdapter extends ArrayAdapter<HashMap<String, Object>>
            implements OnItemSelectedListener {
        boolean[] checkBoxState;
        ViewHolder viewHolder;

        public CustomAdapter(Context context, int textViewResourceId,
                ArrayList<HashMap<String, Object>> arrayListItems) {
            // let android do the initializing :)
            super(context, textViewResourceId, arrayListItems);
            checkBoxState = new boolean[arrayListItems.size()];
        }

        // class for caching the views in a row
        private class ViewHolder {
            CheckBox checkBox;
        }

        @Override
        public View getView(final int position, View convertView,
                ViewGroup parent) {
            Log.d("getView", "getView");
            if (convertView == null) {
                convertView = inflater.inflate(R.layout.activity_orderitem,
                        null);
                viewHolder = new ViewHolder();
                // cache the views
                convertView.setTag(viewHolder);
            } else
                viewHolder = (ViewHolder) convertView.getTag();

            viewHolder.checkBox.setChecked(checkBoxState[position]);

            viewHolder.checkBox.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    if (((CheckBox) v).isChecked()) {
                        checkBoxState[position] = true;
                    } else {
                        checkBoxState[position] = false;
                    }
                }
            });

            return convertView;
        }
    }
}
于 2013-07-30T11:05:48.703 回答
0

您没有正确使用 ViewHolder 模式。您必须创建一个 ViewHolder 并使用 setTag 和 getTag 来存储项目的状态:

    if (convertView == null) {
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }   
于 2013-07-25T10:05:12.573 回答
0

在我看来,您正在使用视图来存储其状态,因此当视图在滚动中被回收时,原始元素会丢失状态,甚至可以将状态分配给获得回收视图的其他元素。尝试不将元素的状态存储在视图中,而是将其存储在适配器中的不同结构中。

于 2013-08-01T08:34:58.100 回答