Урок 42. Список - ListView

Обсуждение уроков
Аватара пользователя
klblk
Сообщения: 1097
Зарегистрирован: 18 окт 2012, 11:17
Откуда: г. Красноярск

Re: Урок 42. Список - ListView

Сообщение klblk » 15 янв 2014, 08:44

Nastasia писал(а):Весь код просто длинный, и там много лишнего, не относящегося к вопросу.

Код: Выделить всё

package com.example.streliba;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;



public class BeginShooting extends Activity implements OnClickListener {

  final String LOG_TAG = "myLogs";

  Button btnAdd, btnRead, butStart, butStop, butPause;
  EditText enterpoints, datat, namee;

  DBHelper dbHelper;
  
  int i=1;
  
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.beginshooting);

    btnAdd = (Button) findViewById(R.id.btnok);
    btnAdd.setOnClickListener(this);

    btnRead = (Button) findViewById(R.id.btnRead);
    btnRead.setOnClickListener(this);    
         
    butStart = (Button) findViewById(R.id.buttonstart);
    butStart.setOnClickListener(this);
    
	butPause = (Button) findViewById(R.id.buttonpause);
	butPause.setOnClickListener(this);
    
	butStop = (Button) findViewById(R.id.buttonstop);
	butStop.setOnClickListener(this);
	
    enterpoints = (EditText) findViewById(R.id.enterpoints);
    namee = (EditText) findViewById(R.id.name);
    
    datat = (EditText) findViewById(R.id.data);  
   
   
    dbHelper = new DBHelper(this);
    String curDate = new SimpleDateFormat("dd.MM.yyyy").format(Calendar.getInstance().getTime());
    datat.setText(curDate);
    
    Chronometer chronometer = (Chronometer) findViewById(R.id.chronometer);
    chronometer.setText("00:00:00");
    

  }

  
  @Override
  public void onClick(View v) {
	    
    ListView listView = (ListView) findViewById(R.id.listpoints);
    // Создаём пустой массив для хранения очков
 	final ArrayList<String> listpoint = new ArrayList<String>();
 // Создаём адаптер ArrayAdapter, чтобы привязать массив к ListView
 	final ArrayAdapter<String> adapter;
 	adapter = new ArrayAdapter<String>(this,
 			android.R.layout.simple_list_item_1, listpoint);
 // Привяжем массив через адаптер к ListView
 	listView.setAdapter(adapter);
    
 // создаем объект для данных
    ContentValues cv = new ContentValues();
    // получаем данные из полей ввода
    String points = enterpoints.getText().toString();
    String name = namee.getText().toString();
    String elapsedTime = "00:00:00";
    // подключаемся к БД
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    String curDate = new SimpleDateFormat("dd.MM.yyyy").format(Calendar.getInstance().getTime());
    Chronometer chronometer = (Chronometer) findViewById(R.id.chronometer);
    String time = (String) chronometer.getText();
    
    
    switch (v.getId()) {
    
    case R.id.buttonstart:
    	chronometer.setBase(SystemClock.elapsedRealtime());
    	chronometer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {

            @Override
            public void onChronometerTick(Chronometer chronometer) {
                CharSequence text = chronometer.getText();
                if (text.length()  == 5) {
                    chronometer.setText("00:"+text);
                } else if (text.length() == 7) {
                    chronometer.setText("0"+text);
                }
            }
        });
        chronometer.start();       
        break;
    case R.id.buttonpause:
    	String pauseq=(String) butPause.getText();    	
    	if(pauseq.equals("Pause")){    		
    		chronometer.stop();    		
    		butPause.setText("Resume");
    		}else{
    		elapsedTime = (String) chronometer.getText();
    		int stoppedMilliseconds=0;
    		String array[]=elapsedTime.split(":");    		
    		stoppedMilliseconds =Integer.parseInt(array[0])*60*60*1000+Integer.parseInt(array[1])*60*1000+Integer.parseInt(array[2])*1000;    		
    		chronometer.setBase(SystemClock.elapsedRealtime()-stoppedMilliseconds);    		
    		chronometer.start();
    		butPause.setText("Pause");
    		}
    	
        break;
    case R.id.buttonstop:
       chronometer.stop();
       break;
    case R.id.btnok:
    	if(points.equals("")){
    		Toast.makeText(this, "Введите результат", Toast.LENGTH_LONG).show();
    	}else{
    	if(name.equals("")){
    		Toast.makeText(this, "Введите имя", Toast.LENGTH_LONG).show();
    	} else if(time=="00:00:00")
    	{
    		Toast.makeText(this, "Включите таймер", Toast.LENGTH_LONG).show();
    	} 
      Log.d(LOG_TAG, "--- Insert in mytable: ---");
           
      cv.put("points", points);
      cv.put("data", curDate);
      cv.put("time", time);
      cv.put("name", name);
      // вставляем запись и получаем ее ID
      long rowID = db.insert("mytable", null, cv);
      Log.d(LOG_TAG, "row inserted, ID = " + rowID);     
      
	  listpoint.add( i+++". "+enterpoints.getText().toString());      
      adapter.notifyDataSetChanged();
	  enterpoints.setText("");
	  }
	  break;
      
    case R.id.btndel:
       
        break;
   
    case R.id.btnRead:
      Log.d(LOG_TAG, "--- Rows in mytable: ---");
      // делаем запрос всех данных из таблицы mytable, получаем Cursor 
      Cursor c = db.query("mytable", null, null, null, null, null, null);

      // ставим позицию курсора на первую строку выборки
      // если в выборке нет строк, вернется false
      if (c.moveToFirst()) {

        // определяем номера столбцов по имени в выборке
        int idColIndex = c.getColumnIndex("id");
        int pointsColIndex = c.getColumnIndex("points");
        int dataColIndex = c.getColumnIndex("data");
        int timeColIndex = c.getColumnIndex("time");
        int nameColIndex = c.getColumnIndex("name");
       
        do {
          // получаем значения по номерам столбцов и пишем все в лог
          Log.d(LOG_TAG,
              "ID = " + c.getInt(idColIndex) + 
              ", points = " + c.getString(pointsColIndex) + 
              ", data = " + c.getString(dataColIndex)+
              ", time = "+c.getString(timeColIndex)+
              ", name = "+c.getString(nameColIndex));
          // переход на следующую строку 
          // а если следующей нет (текущая - последняя), то false - выходим из цикла
        } while (c.moveToNext());
      } else
        Log.d(LOG_TAG, "0 rows");
      c.close();
      break;
   
    }
    // закрываем подключение к БД
    dbHelper.close();
  }
  
  

  class DBHelper extends SQLiteOpenHelper {

    public DBHelper(Context context) {
      // конструктор суперкласса
      super(context, "myDB", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
      Log.d(LOG_TAG, "--- onCreate database ---");
      // создаем таблицу с полями
      db.execSQL("create table mytable ("
          + "id integer primary key autoincrement," 
          + "points text," 
          + "data text,"
          + "time text," 
          + "name text"+");");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
  }

}
вот я так и подумал... почему у вас при каждом клике создается новый адаптер?
делайте это один раз в onCreate(), а в onClick() оставте только добавление нового элемента.

Nastasia
Сообщения: 6
Зарегистрирован: 06 янв 2014, 03:46

Re: Урок 42. Список - ListView

Сообщение Nastasia » 15 янв 2014, 14:26

Мне нужно, чтоб после каждого нажатия кнопки, список обновлялся, для этого я вызываю в onClick adapter.notifyDataSetChanged();
А для этого мне нужно его объявить в onClick, поэтому он и создается там каждый раз.
В общем, что-то у меня не получается)

Аватара пользователя
klblk
Сообщения: 1097
Зарегистрирован: 18 окт 2012, 11:17
Откуда: г. Красноярск

Re: Урок 42. Список - ListView

Сообщение klblk » 16 янв 2014, 06:42

объявите адаптер глобально, как переменную класса. Как-то так:
[syntax=java]
ArrayList<String> listpoint;
ArrayAdapter<String> adapter;

public void onCreate(Bundle savedInstanceState) {
....
ListView listView = (ListView) findViewById(R.id.listpoints);
listpoint = new ArrayList<String>();
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, listpoint);
listView.setAdapter(adapter);
...
}

public void onClick(View v) {
....
switch (v.getId()) {
case R.id.btnok:
listpoint.add(enterpoints.getText().toString());
adapter.notifyDataSetChanged();
enterpoints.setText("");
break;
....
} [/syntax]

Nastasia
Сообщения: 6
Зарегистрирован: 06 янв 2014, 03:46

Re: Урок 42. Список - ListView

Сообщение Nastasia » 16 янв 2014, 15:17

Да, так работает. Спасибо большое!!!)))

Watson
Сообщения: 20
Зарегистрирован: 06 дек 2013, 10:44

Re: Урок 42. Список - ListView

Сообщение Watson » 17 янв 2014, 12:08

Добрый день, почитал тему, посмотрел вопросы, но ответа на свой "нубский" вопрос не нашел :)
В Java не особо силен, объясните, пожалуйста, один момент
[syntax=java]ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, names);[/syntax]
Вот здесь что значит <String>? Про тип адаптера ArrayAdapter я понимаю, что создаем объект new ArrayAdapter тоже понимаю, но этот <String> не могу понять зачем

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Урок 42. Список - ListView

Сообщение KamiSempai » 17 янв 2014, 14:11

Ищите информацию на тему "Дженерики".
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

TittTitov
Сообщения: 27
Зарегистрирован: 20 ноя 2013, 22:46

Re: Урок 42. Список - ListView

Сообщение TittTitov » 18 янв 2014, 13:35

Ребят, а что это за параметры у TextView

Код: Выделить всё

xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="5dp"
что они означают? Спасибо!

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 42. Список - ListView

Сообщение Foenix » 18 янв 2014, 14:23

это отступы от краешков. Поменяй и увидишь на что это влияет.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Аватара пользователя
Люстэн
Сообщения: 10
Зарегистрирован: 31 авг 2013, 20:18
Откуда: UA, Севастополь
Контактная информация:

Re: Урок 42. Список - ListView

Сообщение Люстэн » 09 фев 2014, 20:18

Добавляю в адаптер массив names и приложение запускаясь на планшетке сообщает о ошибке: pid 15837 sig 9

Мож кто знает - что т акое ? Ибо если в создании адаптера не указывать массив для ListView - то всё нормально едет.

Sagittarius
Сообщения: 12
Зарегистрирован: 14 мар 2013, 16:23

Re: Урок 42. Список - ListView

Сообщение Sagittarius » 12 мар 2014, 18:08

Sagittarius писал(а):Я, конечно, извиняюсь за назойливость...
Но неужели здесь никто не знает и никому не интересно, почему развертывание каждого элемента при первой отрисовке происходит по 3 раза?

[syntax=java]14:49:50.878: getView#1, position = 0: convertView == null, inflate newview = TextView@4051f408, newtext = "0"
14:49:50.878: getView#2, position = 1: convertView = TextView@4051f408 oldtext: "0", newtext = "1"
14:49:50.898: getView#3, position = 2: convertView = TextView@4051f408 oldtext: "1", newtext = "2"
14:49:50.898: getView#4, position = 3: convertView = TextView@4051f408 oldtext: "2", newtext = "3"
14:49:50.910: getView#5, position = 4: convertView = TextView@4051f408 oldtext: "3", newtext = "4"
14:49:50.918: getView#6, position = 5: convertView = TextView@4051f408 oldtext: "4", newtext = "5"
14:49:50.918: getView#7, position = 6: convertView = TextView@4051f408 oldtext: "5", newtext = "6"

14:49:50.988: getView#8, position = 0: convertView = TextView@4051f408 oldtext: "6", newtext = "0"
14:49:50.988: getView#9, position = 1: convertView == null, inflate newview = TextView@405251a8, newtext = "1"
14:49:51.188: getView#10, position = 2: convertView == null, inflate newview = TextView@405262e0, newtext = "2"
14:49:51.188: getView#11, position = 3: convertView == null, inflate newview = TextView@40527430, newtext = "3"
14:49:51.188: getView#12, position = 4: convertView == null, inflate newview = TextView@40528580, newtext = "4"
14:49:51.188: getView#13, position = 5: convertView == null, inflate newview = TextView@405296d0, newtext = "5"
14:49:51.197: getView#14, position = 6: convertView == null, inflate newview = TextView@4052a820, newtext = "6"

14:49:51.227: getView#15, position = 0: convertView == null, inflate newview = TextView@4052c1c8, newtext = "0"
14:49:51.227: getView#16, position = 1: convertView = TextView@4052c1c8 oldtext: "0", newtext = "1"
14:49:51.227: getView#17, position = 2: convertView = TextView@4052c1c8 oldtext: "1", newtext = "2"
14:49:51.227: getView#18, position = 3: convertView = TextView@4052c1c8 oldtext: "2", newtext = "3"
14:49:51.227: getView#19, position = 4: convertView = TextView@4052c1c8 oldtext: "3", newtext = "4"
14:49:51.227: getView#20, position = 5: convertView = TextView@4052c1c8 oldtext: "4", newtext = "5"
14:49:51.227: getView#21, position = 6: convertView = TextView@4052c1c8 oldtext: "5", newtext = "6"[/syntax]
И снова здравствуйте.
За пару месяцев научился правильно искать инфу на stackoverflow, и сегодня решил вернуться к своей старо-забыто-забитой проблеме.
Оказалось, по четкому и правильно заданному поиску на stackoverflow можно найти причину гораздо быстрее чем здесь, что довольно печально :(

custom listview adapter getView method being called multiple times

Всё оказалось довольно просто, но вовсе не очевидно: ListView c параметром layout_height="wrap_content" раздувает все ваши строки по несколько раз, так как заранее не знает, сколько именно их поместиться на экран. Проверил, таки да, если изменить это параметр на любое другое значение, первоначальное количество вызовов сокращается в несколько раз.
У меня на экран помещается 7 строк, поэтому:
layout_height="wrap_content":
getCount = 9, getItemId = 2, getItem = 21, getView = 21

layout_height="match_parent":
getCount = 7, getItemId = 2, getItem = 7, getView = 7

Отсюда совет: по возможности не используйте для определения высоты представления списков "wrap_content".
Eclipse, кстати, добавляет на макет ListView именно с этим нежелательным параметром, и в уроке на сайте также используется именно он...

Аватара пользователя
klblk
Сообщения: 1097
Зарегистрирован: 18 окт 2012, 11:17
Откуда: г. Красноярск

Re: Урок 42. Список - ListView

Сообщение klblk » 13 мар 2014, 06:29

Sagittarius писал(а):Оказалось, по четкому и правильно заданному поиску на stackoverflow можно найти причину гораздо быстрее чем здесь, что довольно печально :(
Т.е. из ваших слов получается, что данный форум должен дублировать stackoverflow или то что кто-то за вас на данном форуме должен искать информацию и давать ее вам?
Если я знаю ответ на вопрос я его даю, особенно если вопрос не тривиальный, и думаю большинство поступают точно также.

Ну и задаю вопросы только в случае, если поиск не дал результатов (к сожалению большинство на этот раз поступает не так)

А вообще я рад, что кто-то научился пользоваться поиском)

Sagittarius
Сообщения: 12
Зарегистрирован: 14 мар 2013, 16:23

Re: Урок 42. Список - ListView

Сообщение Sagittarius » 13 мар 2014, 11:57

Должен - не совсем правильное слово. Правильнее, может.
Если кто-то знал бы причину, я думаю он бы поделился решением, или хотя бы направлением поиска. Иначе смысл в существовании форума...
Или если кто-то бы из более опытных захотел бы помочь, то найти нужную инфу ему было бы в 100 раз легче, чем новичку, которому и сформулировать то узкоспециализированный запрос сложно.
В общем, ладно, это всё лирика. Суть в простом решении не очевидной проблемы, которым я поделился, и который, возможно, было бы логично добавить в статью на сайте.

Olelucoye
Сообщения: 4
Зарегистрирован: 19 мар 2014, 14:48

Re: Урок 42. Список - ListView

Сообщение Olelucoye » 19 мар 2014, 15:01

Подскажите, пожалуйста, как программно изменить свойства элемента пункта ListView. Например, с помощью настроек изменить цвет шрифта пунктов списка.

Sagittarius
Сообщения: 12
Зарегистрирован: 14 мар 2013, 16:23

Re: Урок 42. Список - ListView

Сообщение Sagittarius » 19 мар 2014, 15:50

Olelucoye писал(а):Подскажите, пожалуйста, как программно изменить свойства элемента пункта ListView. Например, с помощью настроек изменить цвет шрифта пунктов списка.
Если для каждого пункта отдельно - с помощью своей реализации метода адаптера getView: Урок 54. Кастомизация списка. Создаем свой адаптер

Olelucoye
Сообщения: 4
Зарегистрирован: 19 мар 2014, 14:48

Re: Урок 42. Список - ListView

Сообщение Olelucoye » 19 мар 2014, 19:56

Нет, не к каждому. Ко всем пунктам. Чтобы пользователь мог сам мог определить как будет выглядеть список.
Пытаюсь просто присвоить цвет TextView, который является элементом пункта списка.

Код: Выделить всё

TextView tvItem = (TextView) findViewById(R.id.tvItem);
tvItem.setTextColor(color_value);
Но приложение вылетает на строчке tvItem.setTextColor(color_value)

Аватара пользователя
klblk
Сообщения: 1097
Зарегистрирован: 18 окт 2012, 11:17
Откуда: г. Красноярск

Re: Урок 42. Список - ListView

Сообщение klblk » 20 мар 2014, 07:00

собственно где ищется TextView?
делайте это в getView, ссылку на урок дали выше.

Sagittarius
Сообщения: 12
Зарегистрирован: 14 мар 2013, 16:23

Re: Урок 42. Список - ListView

Сообщение Sagittarius » 20 мар 2014, 10:27

Olelucoye писал(а):Нет, не к каждому. Ко всем пунктам. Чтобы пользователь мог сам мог определить как будет выглядеть список.
Если нужно определить цвета для всех элементов списка, это можно сделать с помощью отдельного стиля, который будет задан для элемента TextView вашего макета строки ArrayAdapter<T>(context,resource). Однако, думаю, для новичка программная работа со стилями будет довольно сложна.
Olelucoye писал(а):[syntax=java]TextView tvItem = (TextView) findViewById(R.id.tvItem);[/syntax]Но приложение вылетает на строчке tvItem.setTextColor(color_value)
Если Вы пытаетесь найти tvItem в основной активности, на которую привязан основной макет (R.layout.main), то это, вероятно, бессмысленно, ведь его там нет. Он по логике должен находиться на макете, который Вы задаете для своего списка ArrayAdapter<T>(context,resource).
Рекомендую не полениться, и таки посмотреть свои реализации адаптеров списка.

vapsel
Сообщения: 16
Зарегистрирован: 23 мар 2014, 00:23

Re: Урок 42. Список - ListView

Сообщение vapsel » 23 мар 2014, 00:29

подскажите, пожалуйста, от чего зависит внешний вид на этой картинки?
это случайно не theme при создании проекта или обособленности AVD?
с картинкой справиться не могу, извиняюсь...
Изображение

Аватара пользователя
klblk
Сообщения: 1097
Зарегистрирован: 18 окт 2012, 11:17
Откуда: г. Красноярск

Re: Урок 42. Список - ListView

Сообщение klblk » 24 мар 2014, 05:42

vapsel писал(а):подскажите, пожалуйста, от чего зависит внешний вид на этой картинки?
это случайно не theme при создании проекта или обособленности AVD?
с картинкой справиться не могу, извиняюсь...
theme

vapsel
Сообщения: 16
Зарегистрирован: 23 мар 2014, 00:23

Re: Урок 42. Список - ListView

Сообщение vapsel » 24 мар 2014, 22:24

klblk писал(а):
vapsel писал(а):подскажите, пожалуйста, от чего зависит внешний вид на этой картинки?
это случайно не theme при создании проекта или обособленности AVD?
с картинкой справиться не могу, извиняюсь...
theme
а его можно поменять после создания проекта?



и еще вопрос, как после вставки кода (при копировании) сделать его сразу структурированым по абзацам как в видеоуроках?

Ответить