android check if item clicked

2019-06-28 07:05发布

问题:

I just started with Android programming and here's the thing.

How can i check if the item in GridView was already clicked? Something like assigning a boolean 'clicked' for EACH item in Grid and changing it's value every time i click the item.

Currently i'm just using an array of bools so if i click item[x] it switches the bool[x] and then i do the check if it's true/false and modify the item accordingly, but there has to be a neater way of doing the same!

My code:

package com.example.mojrecnik;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.AdapterView;
import android.widget.TextView;
import android.widget.Toast;
import android.support.v4.app.NavUtils;

public class Glavna extends Activity implements AdapterView.OnItemClickListener {

    private static final int LENGTH_SHORT = 0;
    GridView grid;
    TextView tekst;
    String[] izfajla = new String[200];
    String[] izfajla2 = new String[200];
    boolean[] kliknutmrs = new boolean[200];

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_glavna);

        grid=(GridView)findViewById(R.id.grid);
        grid.setAdapter(new MojAdapter());
        grid.setOnItemClickListener(this);

        //tekst=(TextView)findViewById(R.id.tekst);

        citaFajl();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_glavna, menu);
        return true;
    }

    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
        TextView klik = (TextView)arg1.findViewById(R.id.gridtekst2);
        if(kliknutmrs[arg2]) {
            kliknutmrs[arg2]=!kliknutmrs[arg2];
            klik.setText(izfajla[arg2]); }
        else {
            kliknutmrs[arg2]=!kliknutmrs[arg2];
            klik.setText(izfajla2[arg2]); }
    }

    public void onNothingSelected(AdapterView<?> arg0) {

    }

    public void citaFajl() {
        File kartica = Environment.getExternalStorageDirectory();
        File fajl = new File(kartica, "reci.txt");
        StringBuilder tekst = new StringBuilder();
        int i=0;
        try {
            BufferedReader br = new BufferedReader(new FileReader(fajl));
            String linija;
            String[] prva;

            while ((linija = br.readLine())!=null) {
                prva = linija.split("-");
                izfajla[i]=prva[0];
                if(prva[1].length()>0)
                    izfajla2[i]=prva[1];
                i++;
            }
        }
        catch (IOException e) {
            Toast greska = Toast.makeText(this, e.getMessage().toString(), LENGTH_SHORT);
            greska.show();
        }
    }

    private class MojAdapter extends ArrayAdapter {

        public MojAdapter() {
            super(Glavna.this, R.layout.gridvju, izfajla);
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            //vazno!! pravim vju od inflatera i vracam vju a ne convertvju!
            View gridvju;

            if(convertView==null) {
                LayoutInflater inflater = getLayoutInflater();
                gridvju = inflater.inflate(R.layout.gridvju, parent, false);
            }
            else
                gridvju=convertView;

            TextView tekst2 = (TextView)gridvju.findViewById(R.id.gridtekst2);
            tekst2.setLines(2);
            tekst2.setText(izfajla[position]);

            return(gridvju);
        }
    }
} 

And XML(main):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
<!--  
    <TextView
        android:id="@+id/tekst"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:textSize="20dp"
        android:layout_below="@id/tekst" >
    </TextView> -->

    <GridView
        android:id="@+id/grid"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:horizontalSpacing="@dimen/padding_medium"
        android:numColumns="3"
        android:stretchMode="columnWidth" >

    </GridView>

</RelativeLayout>

And layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/gridtekst2" />

</LinearLayout>

回答1:

Here is how i worked it in the end. I created a custom class to contain text which is displayed and also added a bool in there so now every element in my gridview has its own 'click-checker'. note: this program simply alternates between 2 words onClick, if you wanna try it use text file with data formated 'word1 - word2'

Code:

package com.example.mojrecnik;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.AdapterView;
import android.widget.TextView;
import android.widget.Toast;

public class Glavna extends Activity implements AdapterView.OnItemClickListener {

    private static final int LENGTH_LONG = 1;
    GridView grid;
    List<Rec> lReci = new ArrayList<Rec>(); //this is our list of data which contains text and bool check

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_glavna);

        citaFajl();

        grid=(GridView)findViewById(R.id.grid);
        grid.setAdapter(new MojAdapter());
        grid.setOnItemClickListener(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_glavna, menu);
        return true;
    }

    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
        VjuHolder holder=(VjuHolder)arg1.getTag();

        if(!lReci.get(arg2).clicked)
            holder.text.setText(lReci.get(arg2).rec2);
        else
            holder.text.setText(lReci.get(arg2).rec1);

        lReci.get(arg2).clicked = !lReci.get(arg2).clicked;
    }

    public void onNothingSelected(AdapterView<?> arg0) {
        //////////////////////////////////////////
    }

    public void citaFajl() {

        try {
            BufferedReader br = new BufferedReader(new FileReader(new File(Environment.getExternalStorageDirectory(), "reci.txt")));
            String[] reci = new String[2];
            String linija;
            Rec rec;

            while ((linija = br.readLine()) != null) {
                reci = linija.split("-"); //because data in my file is formatted 'word1 - word2', we separate them now so we can alternate between them
                reci[1]=reci[1].trim();
                rec = new Rec(reci[0], reci[1], false);
                lReci.add(rec);
            }
        }
        catch (IOException e) {
            Toast.makeText(this, e.getMessage().toString(), LENGTH_LONG).show();
        }
    }

    private class MojAdapter extends ArrayAdapter<String> {

        public MojAdapter() {
            super(Glavna.this, R.layout.gridvju);
        }

        public int getCount() {
            return lReci.size(); //here we explicitly set the total number of grid elements so it doesn't go out of index range
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            VjuHolder holder;

            if(convertView==null) {
                LayoutInflater inflater = getLayoutInflater();
                convertView = inflater.inflate(R.layout.gridvju, parent, false);
                holder = new VjuHolder();
                holder.text = (TextView)convertView.findViewById(R.id.gridtekst2);
                convertView.setTag(holder); }
            else
                holder=(VjuHolder)convertView.getTag();

                if(lReci.get(position).clicked) //check to make grid update according to the clicked state of our elements [when scrolling]
                    holder.text.setText(lReci.get(position).rec2);
                else
                    holder.text.setText(lReci.get(position).rec1);

                holder.text.setLines(2);

            return(convertView);
        }
    }
}

//holder class
class VjuHolder {
    TextView text;
}

//here we put the text to be displayed along with bool to check in which state is the clicked element
class Rec {
    String rec1, rec2;
    boolean clicked;

    Rec(String rec, String druga, boolean klik) {
        rec1 = rec;
        rec2 = druga;
        clicked = klik;
    }
}


回答2:

There's no such thing like "click history" retained. If user taps anything then, if there's onClickListener assigned, you will get notified about that tap. But you cannot check that by querying UI objects. Boolean array is ok, but I'd use List or ArrayList instead and simply add id of tapped items in my onClickListener.



回答3:

There is no way to find out whether button was clicked before or not. I think you've been looking for some sort of class property like

    if(button.wasOnceClicked){         //THERE IS NO CODE LIKE THIS
    }

Am I right? Well, Button class dont have this. However u can create subclass of Button and add that property and also add some code which will handle that property.



回答4:

First of all initialize your boolean array in onCreate as:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_grid);

    grid=(GridView)findViewById(R.id.grid);
    grid.setAdapter(new MojAdapter());
    grid.setOnItemClickListener(this);

  //   HERE  I have initialized with true valuse
    for(int i=0; i<kliknutmrs.length; i++) {
        kliknutmrs[i] = true;
    }
   //tekst=(TextView)findViewById(R.id.tekst);

   citaFajl();
}

Then at onClick, just ckeck that the boolean array hav "true" value; so make that position value "false" and same time invert the text value with another String[] array.

At second time it will goto to else part:

public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
    TextView klik = (TextView)arg1.findViewById(R.id.gridtekst2);
    if(kliknutmrs[arg2]) {
        System.out.println(" ------------ 11111111111 -----------");
        kliknutmrs[arg2]=!kliknutmrs[arg2];
        klik.setText(izfajla2[arg2]); }
    else {
        System.out.println(" ------------- 222222222 -----------");
                //  NO  NEED   //kliknutmrs[arg2]=!kliknutmrs[arg2];
        klik.setText(izfajla2[arg2]); }
}