Как написать справочник на андроид

Время на прочтение
20 мин

Количество просмотров 26K

Здравствуйте, уважаемые Хабровчане! Вы видели немало постов на тему разработки под android. В данном посте я попытаюсь наиболее подробно изложить свой небольшой опыт разработки под эту ОС.

Небольшое вступление

Проанализировав маркет я понял, что на нем очень много игр, развлекательных и социальных приложений. По-настоящему нужных приложений очень мало, поэтому я решил сделать «карманный» справочник по высшей математике с удобной навигацией по темам, состоящий из трех разделов: математический анализ, аналитическая геометрия, теория вероятностей. Далее обо всем по порядку.

Структура приложения

О создании приложения такого плана на Хабре уже писали в посте

Пишем шпаргалку на Android

. Разумеется есть некоторые отличия. Первое и главное из них в том, что в нашем приложении нужно будет сделать чуть побольше Activity, второе — добавление в приложение социальных возможностей, таких как отправить письмо разработчику и самостоятельно поучаствовать в создании приложения любому желающему, также добавим в приложение меню опций и несколько диалоговых окон, ну и собственно подключим к нему рекламу Begun, чтобы хоть как-то оправдать затраты на приобретение аккаунта разработчика на маркете.

Activity

MainActivity

При запуске приложения пользователь будет видеть экран MainActivity:
image
Он содержит три кнопки, при нажатии на которые осуществляется переход на MatanActivity, GeomActivity, или TerverActivity, содержащие в своих файлах-разметки элементы ListView, представляющие набор соответствующих тем по нужному предмету. Подробный код MainActivity представлен ниже:

public class MainActivity extends Activity {
AdView ad;
//Объявление идентификатора диалогового окна HELP и диалогового окна Exit
static final int EXIT_DIALOG=0;
static final int HELP_DIALOG=1;//Вызов меню опций с одной кнопкой About
   
Override
   public boolean onCreateOptionsMenu(Menu menu) {
       MenuInflater inflater = getMenuInflater();
       inflater.inflate(R.menu.gameoptions, menu);
       menu.findItem(R.id.about_menu_item);
       menu.findItem(R.id.btn_email);
       return true;
   }
  //обработка нажатий на эл-ты меню опций
   //Вызов диалога HELP из меню опций при нажатии на «О приложении» и переход на EmailActivity при нажатии на «свяжитесь с нами»
   
Override
   public boolean onOptionsItemSelected(MenuItem item) {
   switch (item.getItemId()) {
    case R.id.about_menu_item:
        showDialog(HELP_DIALOG);
        return true;
    case R.id.btn_email:
     startActivity(new Intent(getApplicationContext(),EmailActivity.class));
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
   }/** Called when the activity is first created. */

Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); //скрываем заголовок
setContentView(R.layout.second);   //подключение рекламы
// Получаем вид
ad = (AdView)findViewById(R.id.ad);
ad.onDebug = true; 
// Устанавливаем слушатели событий
// callback — слушатель, благодаря которому можно получить информацию
// о событиях в библиотеке. Пока доступны следующие листенеры: AdLoaded, AdClickThru
// и AdStopped. Для инициализации необходимо передать параметр environmentVars,
// который содержит информацию о зарегистрированной площадке в системе
// (BEGUN_PAD_ID, BEGUN_BLOCK_ID).
// Для начала инициализации необходимо вызвать метод ad.init. Затем дождаться
// callback со статусом adLoaded и только после этого вызвать метод
// ad.api(«initAd»,al);
ad.setOnApiListener(new Callback() {

Override
public void init() {
Log.d(«BEGUN_AD»«ad.api|initAd»); 
ArrayList<RequestParam> al = new ArrayList<RequestParam>();
RequestParam rp = new RequestParam();
rp.name = «environmentVars»;
rp.value = «pad_id:261629112|block_id:261629500»;
al.add(rp);
ad.api(«initAd», al);
Log.d(«BEGUN_AD»«CALLBACK params: « + al.toString()); 
}

Override
public void callback(String c) {
Log.d(«BEGUN_AD»«CALLBACK API : « + c); 
if (c.equals(«AdLoaded»)) {
Log.d(«BEGUN_AD»«startAd « + c);
ad.api(«startAd»);
}
}
});
        Log.d(«BEGUN_AD»«ad.init»); 
ad.init();//Запуск MatanActivity
    Button b=(Button)this.findViewById(R.id.btn_mathan);
        b.setOnClickListener(new OnClickListener(){
         public void onClick(View arg0){
         startActivity(new Intent(getApplicationContext(),MatanActivity.class));
         }
        }); //Запуск GeomActivity
     Button d=(Button)this.findViewById(R.id.btn_geom);
        d.setOnClickListener(new OnClickListener(){
         public void onClick(View arg0){
         startActivity(new Intent(getApplicationContext(),GeomActivity.class));
         }
        }); //Запуск TerverActivityButton c=(Button)this.findViewById(R.id.btn_terver);
        c.setOnClickListener(new OnClickListener(){
         public void onClick(View arg0){
         startActivity(new Intent(getApplicationContext(),TerverActivity.class));
         }
        });}protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Log.d(«BEGUN_AD»«resumeAd»);
ad.api(«resumeAd»);
} //Создание диалоговых окон HELP_DIALOG и EXIT_DIALOG
     
Override
      protected Dialog onCreateDialog(int id)
{
     switch (id) 
{
case HELP_DIALOG:
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.help,
                               (ViewGroup) findViewById(R.id.root));
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(layout)
       .setCancelable(true)
       .setTitle(«О приложении»)
       .setNeutralButton(«ОК»new DialogInterface.OnClickListener() 
       {
           public void onClick(DialogInterface dialog, int id) 
           {
                dialog.cancel();
           }  
       });
    AlertDialog alert = builder.create();
    return builder.create();case EXIT_DIALOG:
AlertDialog.Builder builder3 = new AlertDialog.Builder(this);
                builder3.setMessage(«Уверены, что хотите выйти?»)
                        .setCancelable(false)
                        .setPositiveButton(«Да»new DialogInterface.OnClickListener() {
                       public void onClick(DialogInterface dialog, int id) {
                            SecondActivity.this.finish();
                       }
                   })
                   .setNegativeButton(«Нет»new DialogInterface.OnClickListener() {
                       public void onClick(DialogInterface dialog, int id) {
                            dialog.cancel();
                       }});
            AlertDialog alert3 = builder3.create();
            return builder3.create();default:
return null;
}}//Вызов диалога EXIT_DIALOG при нажатии на клавишу back смартфона
          
Override
          public void onBackPressed (){
          showDialog(EXIT_DIALOG);    
      }}
 

Диалоговое окно «О приложении»
image

Диалоговое окно выхода из приложения
image

Реклама добавлена в приложение больше из интереса, чем из коммерческих соображений, т.к. очевидно, что на русском приложении много не заработать. Поэтому я подключил в него чисто русскую рекламу системы Begun, до этого на Хабре многое писалось про подключение рекламы, но в основном это были зарубежные «конторы».

Плюсы использования рекламы Бегун

1. Удобный, качественный API.
2. Удобный вывод денег на WebMoney.
3. Хорошая служба поддержки, стабильно отвечающая на любые ваши вопросы.

Минусы использования рекламы Бегун

Единственный минус заключается в том, что оплата осуществляется только за переходы, но в скором времени обещают запустить систему оплаты и за клики, и за показы.

Как подключить рекламу BEGUN

1. Заходим на сайт бегуна в раздел партнерам.
2. Жмем «Стать партнером».
3. Заполняем анкету.
4. Жмем зарегестрироваться.
5. Далее входим в свой кабинет на сайте.
6. В правом верхнем углу жмете «Написать» (Перейдете в меню написания письма в службу поддержки).
7. Пишите в службу поддержки о том, что у вас есть android-приложение и вы бы хотели подключить в него рекламу Begun, вам вышлют ваш pad_id и block_id, которые в ы и вставляете в код, написанный выше, вместо тегов <Ваш pad_id> <Ваш block_id>.

Интеграция рекламы Begun в приложение

1. В classpath проекта необходимо добавить jar — библиотеку рекламы, доступную
по адресу appsmobile.begun.ru/begunAdView.jar.
2. Необходимо добавить в layout следующий блок:

<ru.begun.adlib.AdView
android:id=«@+id/ad»
android:orientation=«vertical»
android:layout_width=«fill_parent»
android:layout_height=«wrap_content»
android:layout_alignParentBottom=«true»
/>

В качестве родительского слоя рекомендуется использовать RelativeLayout.
3. Файл манифеста необходимо добавить следующие разрешения:

<uses-permission android:name=«android.permission.INTERNET»/>
<uses-permission android:name=«android.permission.ACCESS_COARSE_LOCATION»/>
<uses-permission android:name=«android.permission.READ_PHONE_STATE»/>

4. Инициализация библиотеки происходит следующим образом:

import ru.begun.adlib.AdView;
import ru.begun.adlib.Callback;
import ru.begun.adlib.RequestParam;
AdView ad;
// Получаем вид
ad = (AdView)findViewById(R.id.ad);
// Устанавливаем слушатели событий
// callback — слушатель, благодаря которому можно получить информацию
// о событиях в библиотеке. Пока доступны следующие листенеры: AdLoaded, AdClickThru
// и AdStopped. Для инициализации необходимо передать параметр environmentVars,
// который содержит информацию о зарегистрированной площадке в системе
// (BEGUN_PAD_ID, BEGUN_BLOCK_ID).
// Для начала инициализации необходимо вызвать метод ad.init. Затем дождаться
// callback со статусом adLoaded и только после этого вызвать метод
// ad.api(«initAd»,al);
ad.setOnApiListener(new Callback() {

Override
public void init() {
ArrayList<RequestParam> al = new ArrayList<RequestParam>();
RequestParam rp = new RequestParam();
rp.name = «environmentVars»;
rp.value = «pad_id:<BEGUN_PAD_ID>|block_id:<BEGUN_BLOCK_ID>»;
al.add(rp);
ad.api(«initAd», al);
}

Override
public void callback(String c) {
if (c.equals(«AdLoaded»)) {
ad.api(«startAd»);
}
}
});
ad.init();

Для возобновления показа рекламных объявлений после того, как библиотека была остановлена,
необходимо вызвать метод ad.api с параметром resumeAd.

Все, реклама подключена и работает!

main.xml

Файл-разметки MainActivity.

<?xml version=«1.0» encoding=«utf-8»?>
<RelativeLayout xmlns:android=«schemas.android.com/apk/res/android»
    android:orientation=«vertical»
    android:layout_width=«fill_parent»
    android:layout_height=«fill_parent»
    android:weightSum=«1» 
    android:background=«@drawable/main_1»><Button
android:id=«@+id/btn1»
android:layout_width=«wrap_content»
android:layout_height=«wrap_content»
android:background=«@layout/button_selector_leftcorner»/><Button android:textStyle=«bold» android:textColor=«#FFC000» android:background=«@layout/button_selector» android:layout_height=«wrap_content» android:layout_width=«173dp» android:text=«Ан. геометрия и лин. алгебра» android:id=«@+id/btn_geom» android:layout_above=«@+id/btn_terver» android:layout_alignLeft=«@+id/btn_terver» android:layout_marginBottom=«16dp»></Button>
    <Button android:textStyle=«bold» android:textColor=«#FFC000» android:background=«@layout/button_selector»  android:layout_height=«wrap_content» android:layout_width=«173dp» android:text=«Математический      анализ» android:id=«@+id/btn_mathan» android:layout_above=«@+id/btn_geom» android:layout_alignLeft=«@+id/btn_geom» android:layout_marginBottom=«15dp»></Button>
    <Button android:textStyle=«bold» android:textColor=«#FFC000» android:background=«@layout/button_selector»  android:layout_height=«wrap_content» android:layout_width=«173dp» android:text=«Теория                      вероятностей» android:id=«@+id/btn_terver» android:layout_alignParentBottom=«true» android:layout_centerHorizontal=«true» android:layout_marginBottom=«186dp»></Button>
    <ImageView android:id=«@+id/imageView1» android:src=«@drawable/andro» android:layout_height=«wrap_content» android:layout_width=«wrap_content» android:layout_above=«@+id/btn_mathan» android:layout_centerHorizontal=«true»></ImageView>
       <RelativeLayout android:layout_height=«wrap_content» android:layout_width=«fill_parent»>
          <ImageView android:id=«@+id/imageView2» android:layout_height=«wrap_content» android:layout_width=«wrap_content» android:src=«@drawable/title» android:layout_alignParentTop=«true» android:layout_centerHorizontal=«true» android:layout_marginTop=«18dp»></ImageView>
       </RelativeLayout>             
   <ru.begun.adlib.AdView
      android:id=«@+id/ad»
      android:orientation=«vertical»
      android:layout_width=«fill_parent»
      android:layout_height=«wrap_content»
      android:layout_alignParentBottom=«true»
    /><ImageView
    android:id=«@+id/splashscreen»
    android:layout_width=«fill_parent»
    android:layout_height=«fill_parent»
    android:src=«@drawable/splashscreen» android:background=«#000»> 
    </ImageView></RelativeLayout>
 

MatanActivity, GeomActivity и TerverActivity

image

После клика по элементам списка в MatanActivity, GeomActivity или TerverActivity будет осуществляться переход на соответствующую деятельность отображения материала по данной теме ViewMatanActivity, ViewGeomActivity или ViewTerverActivity

image

Код этих активити аналогичен указанным в посте

Пишем шпаргалку на Android

.

Единственное замечание во всех ViewActivity вместо кода:

WebView myWebView = (WebView) findViewById(R.id.webview);
String summary = «<html><body>» + text + «</body></html>»;
myWebView.loadData(summary, «text/html»«utf-8»); //загружаем текст в webview

лучше писать так:

WebView myWebView = (WebView) findViewById(R.id.webview);
String summary = «<html><body>» + text + «</body></html>»;  
myWebView.loadDataWithBaseURL(«x-data://base»,summary, «text/html»«utf-8»null);

В противном случае код будет некорректно работать на устройствах с android 3.2. и некоторых других.

EmailActivity

EmailActivity реализует отправку письма со своими пожеланиями и предложениями разработчикам, а также представляет возможность перехода на страницу приложения в маркете.
image

public class EmailActivity extends Activity {
 Button send;
  EditText address, subject, emailtext;

 
  
Override

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE); //скрываем заголовок
    setContentView(R.layout.email);Button b=(Button)this.findViewById(R.id.btn_market);
        b.setOnClickListener(new OnClickListener(){
         public void onClick(View arg0){
         Uri address=Uri.parse(«market.android.com/details?id=com.mathhelper.math»);
         Intent surf=new Intent(Intent.ACTION_VIEW, address);
         startActivity(surf);
         }
        }); // Наши поля и кнопка
    send = (Button) findViewById(R.id.emailsendbutton);
    address = (EditText) findViewById(R.id.emailaddress);
    //subject = (EditText) findViewById(R.id.emailsubject);
    emailtext = (EditText) findViewById(R.id.emailtext);

 
    send.

setOnClickListener(new OnClickListener() {

 
      
Override

public void onClick(View v) {final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);

 
        emailIntent.

setType(«plain/text»);
        // Кому
        emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,new String[] { address.getText().toString() });// О чём
        emailIntent.putExtra(android.content.Intent.EXTRA_TEXT,emailtext.getText().toString());

 
        EmailActivity.

this.startActivity(Intent.createChooser(emailIntent,
            «Отправка письма»));
      }
    });
  }
}

email.xml

Файл разметки EmailActivity

<?xml version=«1.0» encoding=«utf-8»?>
<RelativeLayout xmlns:android=«schemas.android.com/apk/res/android»
    android:orientation=«vertical»
    android:layout_width=«fill_parent»
    android:layout_height=«fill_parent»
    android:weightSum=«1»><ScrollView 
    android:scrollbars=«vertical»
    android:layout_width=«fill_parent»
    android:layout_height=«fill_parent»>    
    <LinearLayout android:orientation=«vertical» android:id=«@+id/linearLayout2» android:background=«@drawable/metall» android:layout_alignParentTop=«true» android:layout_alignParentLeft=«true» android:layout_marginTop=«40dp» android:layout_width=«fill_parent» android:layout_height=«197dp»>
        <TextView android:layout_width=«wrap_content» android:text=«Напишите нам:» android:layout_height=«wrap_content» android:id=«@+id/textView1» android:gravity=«left»  android:textSize=«10pt» android:textStyle=«normal»></TextView>
        <EditText android:id=«@+id/emailaddress» android:layout_width=«fill_parent» android:layout_height=«wrap_content» android:text=«svdsoftware@gmail.com»></EditText>
        <EditText android:id=«@+id/emailtext» android:layout_width=«fill_parent» android:layout_height=«wrap_content» android:text=«Ваш отзыв…»></EditText>
        <RelativeLayout android:layout_height=«wrap_content» android:layout_width=«fill_parent» android:id=«@+id/relativeLayout1»>
            <TextView android:id=«@+id/textView1» android:text=«Отправить нам email →» android:layout_width=«wrap_content» android:gravity=«left» android:layout_height=«wrap_content» android:textSize=«9pt» android:textStyle=«normal» android:layout_centerVertical=«true»></TextView>
            <Button android:id=«@+id/emailsendbutton» android:layout_width=«wrap_content» android:layout_height=«wrap_content» android:background=«@layout/button_selector_email» android:layout_alignParentTop=«true» android:layout_alignParentRight=«true»></Button>
        </RelativeLayout>
        <RelativeLayout android:id=«@+id/relativeLayout2» android:layout_height=«wrap_content» android:layout_width=«fill_parent»>
            <Button android:id=«@+id/btn_market» android:layout_width=«wrap_content» android:layout_height=«wrap_content» android:background=«@layout/button_selector_am» android:layout_alignParentTop=«true» android:layout_alignParentRight=«true»></Button>
            <TextView android:id=«@+id/textView1» android:text=«Оценить на маркете  →» android:layout_width=«wrap_content» android:gravity=«left» android:layout_height=«wrap_content» android:textSize=«9pt» android:textStyle=«normal» android:layout_centerVertical=«true» ></TextView>
        </RelativeLayout>
    </LinearLayout>
    </ScrollView></RelativeLayout>
 

Заключение

Надеюсь, что пост будет полезен начинающим разработчикам.
Результат всей работы можно найти здесь.

Пишем справочник про котов

В этой статье я покажу как сделать простейшую программу Справочник про котов. На этом примере можно сделать огромное количество полезных приложений — например, небольшой сборник рецептов или набор схем оригами, если использовать ListView с миниатюрами.

Что мы узнаем:

  • Как сделать простой список из массива, используя ListView
  • Как загрузить текст из ресурсов
  • Как загрузить html-текст в WebView
  • Как передать данные из одной активности в другую

Пример морально устарел. Теперь уже не используют ListView и отдельные активности для разделов. Вместо них следует использовать RecyclerView и фрагменты. Но для общего развития всё-равно полезно изучить пример.

Создаём новый проект Manual (не путать с манулом). Начнём с интерфейса программы. Программа будет состоять из двух активностей. В первой выводится список тем, а во второй — полное описание выбранной темы. Откроем разметку первой активности res/layout/activity_main.xml и добавим компонент ListView для отображения списка тем:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    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"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent" />

</LinearLayout>

Сразу же создадим вторую активность DetailActivity (правой кнопкой мыши по имени пакета и выбираем New | Activity | Empty Activity). Создадим разметку для второй активности в файле res/layout/activity_detail.xml. Сюда мы добавим только компонент WebView. Скрытие строки состояния и заголовка сделаем в коде.


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

    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

Дизайн приложения готов. Осталось написать код. Открываем файл класса MainActivity. В нём программно создадим список заголовков тем справочника и через адаптер добавим в список. Когда пользователь выбирает элемент списка, то получаем позицию выбранного элемента и запоминаем его. А затем запускаем вторую активность, в которую передаём номер позиции. Мы проходили подобные вещи раньше, поэтому просто освежите свою память.


// Kotlin
// Если этот код работает, его написал Александр Климов,
// а если нет, то не знаю, кто его писал.
// http://developer.alexanderklimov.ru/android/

package ru.alexanderklimov.manual

import android.content.Intent
import android.os.Bundle
import android.widget.AdapterView.OnItemClickListener
import android.widget.ArrayAdapter
import android.widget.ListView
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

    //Создаем массив разделов:
    private val titles = arrayOf(
        "00. Начало",
        "01. Чем кормить кота",
        "02. Как гладить кота",
        "03. Как спит кот",
        "04. Как играть с котом",
        "05. Как разговаривать с котом",
        "06. Интересные факты из жизни котов",
        "07. Как назвать кота"
    )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
		
        setContentView(R.layout.activity_main)

        val listView: ListView = findViewById(R.id.listView)
        listView.adapter = ArrayAdapter<Any?>(this, android.R.layout.simple_list_item_1, titles)
        listView.isTextFilterEnabled = true

        listView.onItemClickListener =
            OnItemClickListener { a, v, position, id ->
                val intent = Intent()
                intent.setClass([email protected], DetailActivity::class.java)
                intent.putExtra("title", position)

                startActivity(intent)
            }
    }
}

// Java package ru.alexanderklimov.manual; import android.content.Intent; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; public class MainActivity extends AppCompatActivity { //Создаём массив разделов: private String titles[] = { "00. Начало", "01. Чем кормить кота", "02. Как гладить кота", "03. Как спит кот", "04. Как играть с котом", "05. Как разговаривать с котом", "06. Интересные факты из жизни котов", "07. Как назвать кота", }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Получим идентификатор ListView ListView listView = findViewById(R.id.listView); //устанавливаем массив в ListView listView.setAdapter( new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, titles)); listView.setTextFilterEnabled(true); //Обрабатываем щелчки на элементах ListView: listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> a, View v, int position, long id) { Intent intent = new Intent(); intent.setClass(MainActivity.this, DetailActivity.class); intent.putExtra("title", position); //запускаем вторую активность startActivity(intent); } }); } }

Справочник про котов

Вторая активность

Запустив пример, вы можете щёлкнуть по любому элементу списка, чтобы открыть вторую активность. Сейчас вторая активность пуста, так как мы не написали никакого кода. Но при этом она получает номер позиции выбранного элемента через метод putExtra(). В зависимости от полученного номера мы формируем содержание веб-страницы.

Для справочника удобнее держать заранее подготовленные локальные файлы, чтобы не зависеть от интернета. Создадим новую папку — выбираем res | New | Directory и в диалоговом окне вводим имя папки raw.

Самостоятельно подготовьте текстовые файлы с именами n0.txt, n1.txt, n2.txt и т.д. Символ n в начале имён файлов понадобился, чтобы избежать конфликта. Файлы ресурсов не должные начинаться на цифру.

Напишем код для второй активности. Во-первых, получим номер позиции, которую нам прислала первая активность. Во-вторых, открываем нужный файл для чтения и помещаем его содержимое в WebView.


// Kotlin
package ru.alexanderklimov.manual

import android.content.Context
import android.os.Bundle
import android.webkit.WebView
import androidx.appcompat.app.AppCompatActivity
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader


class DetailActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_detail)

        val webView: WebView = findViewById(R.id.webView)

        val intent = intent
        //получаем строку и формируем имя ресурса
        val resName = "n" + intent.getIntExtra("title", 0)

        val context: Context = baseContext

        //читаем текстовый файл из ресурсов по имени
        val text: String = readRawTextFile(
            context, resources.getIdentifier(
                resName,
                "raw", "ru.alexanderklimov.manual"
            )
        )

        webView.loadDataWithBaseURL(null, text, "text/html", "en_US", null)
    }

    //читаем текст из raw-ресурсов
    private fun readRawTextFile(context: Context, resId: Int): String {
        val inputStream: InputStream = context.resources.openRawResource(resId)
        val inputReader = InputStreamReader(inputStream)
        val buffReader = BufferedReader(inputReader)
        var line: String?
        val builder = StringBuilder()
        try {
            while (buffReader.readLine().also { line = it } != null) {
                builder.append(line)
                builder.append("n")
            }
        } catch (e: IOException) {
            return e.localizedMessage
        }
        return builder.toString()
    }
}

// Java package ru.alexanderklimov.manual; import android.content.Context; import android.content.Intent; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import android.util.Log; import android.webkit.WebView; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; public class DetailActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_detail); WebView webView = findViewById(R.id.webView); Intent intent = getIntent(); //получаем строку и формируем имя ресурса String resName = "n" + intent.getIntExtra("title", 0); Log.i("name", resName); Context context = getBaseContext(); //получаем контекст //читаем текстовый файл из ресурсов по имени String text = readRawTextFile(context, getResources().getIdentifier(resName, "raw", "ru.alexanderklimov.manual")); webView.loadDataWithBaseURL(null, text, "text/html", "en_US", null); } //читаем текст из raw-ресурсов private String readRawTextFile(Context context, int resId) { InputStream inputStream = context.getResources().openRawResource(resId); InputStreamReader inputReader = new InputStreamReader(inputStream); BufferedReader buffReader = new BufferedReader(inputReader); String line; StringBuilder builder = new StringBuilder(); try { while (( line = buffReader.readLine()) != null) { builder.append(line); builder.append("n"); } } catch (IOException e) { return null; } return builder.toString(); } }

Запускаем проект и проверяем, что всё работает.

Справочник про котов

Раньше программу можно было скачать в Google Play. На данный момент я отказался от дальнейшей поддержки приложения и Гугл удалила мою программу. Взамен я создал веб-версию.

В примере показаны базовые функции, достаточные для понимания. Вы можете усложнить пример, добавив поддержку фрагментов. Также вы можете самостоятельно доработать пример. Например, добавить картинки к элементам списка, загружать готовые html-документы, а также загружать веб-страницы из интернета.

Дополнительное чтение

Обсуждение статьи на форуме.

Реклама

import android.Manifest;

import android.content.DialogInterface;

import android.content.Intent;

import android.database.Cursor;

import android.net.Uri;

import android.os.Bundle;

import android.provider.ContactsContract;

import android.provider.Settings;

import android.view.Menu;

import android.view.MenuInflater;

import android.view.MenuItem;

import android.view.View;

import android.widget.ProgressBar;

import android.widget.SearchView;

import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;

import androidx.appcompat.app.AppCompatActivity;

import androidx.core.view.MenuItemCompat;

import androidx.recyclerview.widget.LinearLayoutManager;

import androidx.recyclerview.widget.RecyclerView;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import com.karumi.dexter.Dexter;

import com.karumi.dexter.MultiplePermissionsReport;

import com.karumi.dexter.PermissionToken;

import com.karumi.dexter.listener.DexterError;

import com.karumi.dexter.listener.PermissionRequest;

import com.karumi.dexter.listener.PermissionRequestErrorListener;

import com.karumi.dexter.listener.multi.MultiplePermissionsListener;

import java.util.ArrayList;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private ArrayList<ContactsModal> contactsModalArrayList;

    private RecyclerView contactRV;

    private ContactRVAdapter contactRVAdapter;

    private ProgressBar loadingPB;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        contactsModalArrayList = new ArrayList<>();

        contactRV = findViewById(R.id.idRVContacts);

        FloatingActionButton addNewContactFAB = findViewById(R.id.idFABadd);

        loadingPB = findViewById(R.id.idPBLoading);

        prepareContactRV();

        requestPermissions();

        addNewContactFAB.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                Intent i = new Intent(MainActivity.this, CreateNewContactActivity.class);

                startActivity(i);

            }

        });

    }

    @Override

    public boolean onCreateOptionsMenu(Menu menu) {

        MenuInflater inflater = getMenuInflater();

        inflater.inflate(R.menu.search_menu, menu);

        MenuItem searchViewItem = menu.findItem(R.id.app_bar_search);

        final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchViewItem);

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

            @Override

            public boolean onQueryTextSubmit(String query) {

                searchView.clearFocus();

                return false;

            }

            @Override

            public boolean onQueryTextChange(String newText) {

                filter(newText.toLowerCase());

                return false;

            }

        });

        return super.onCreateOptionsMenu(menu);

    }

    private void filter(String text) {

        ArrayList<ContactsModal> filteredlist = new ArrayList<>();

        for (ContactsModal item : contactsModalArrayList) {

            if (item.getUserName().toLowerCase().contains(text.toLowerCase())) {

                filteredlist.add(item);

            }

        }

        if (filteredlist.isEmpty()) {

            Toast.makeText(this, "No Contact Found", Toast.LENGTH_SHORT).show();

        } else {

            contactRVAdapter.filterList(filteredlist);

        }

    }

    private void prepareContactRV() {

        contactRVAdapter = new ContactRVAdapter(this, contactsModalArrayList);

        contactRV.setLayoutManager(new LinearLayoutManager(this));

        contactRV.setAdapter(contactRVAdapter);

    }

    private void requestPermissions() {

        Dexter.withActivity(this)

                .withPermissions(Manifest.permission.READ_CONTACTS,

                        Manifest.permission.CALL_PHONE,

                        Manifest.permission.SEND_SMS, Manifest.permission.WRITE_CONTACTS)

                .withListener(new MultiplePermissionsListener() {

                    @Override

                    public void onPermissionsChecked(MultiplePermissionsReport multiplePermissionsReport) {

                        if (multiplePermissionsReport.areAllPermissionsGranted()) {

                            getContacts();

                            Toast.makeText(MainActivity.this, "All the permissions are granted..", Toast.LENGTH_SHORT).show();

                        }

                        if (multiplePermissionsReport.isAnyPermissionPermanentlyDenied()) {

                            showSettingsDialog();

                        }

                    }

                    @Override

                    public void onPermissionRationaleShouldBeShown(List<PermissionRequest> list, PermissionToken permissionToken) {

                        permissionToken.continuePermissionRequest();

                    }

                }).withErrorListener(new PermissionRequestErrorListener() {

            @Override

            public void onError(DexterError error) {

                Toast.makeText(getApplicationContext(), "Error occurred! ", Toast.LENGTH_SHORT).show();

            }

        })

                .onSameThread().check();

    }

    private void showSettingsDialog() {

        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);

        builder.setTitle("Need Permissions");

        builder.setMessage("This app needs permission to use this feature. You can grant them in app settings.");

        builder.setPositiveButton("GOTO SETTINGS", new DialogInterface.OnClickListener() {

            @Override

            public void onClick(DialogInterface dialog, int which) {

                dialog.cancel();

                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);

                Uri uri = Uri.fromParts("package", getPackageName(), null);

                intent.setData(uri);

                startActivityForResult(intent, 101);

            }

        });

        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

            @Override

            public void onClick(DialogInterface dialog, int which) {

                dialog.cancel();

            }

        });

        builder.show();

    }

    private void getContacts() {

        String contactId = "";

        String displayName = "";

        Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");

        if (cursor.getCount() > 0) {

            while (cursor.moveToNext()) {

                int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));

                if (hasPhoneNumber > 0) {

                    contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));

                    displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

                    Cursor phoneCursor = getContentResolver().query(

                            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,

                            null,

                            ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",

                            new String[]{contactId},

                            null);

                    if (phoneCursor.moveToNext()) {

                        String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

                        contactsModalArrayList.add(new ContactsModal(displayName, phoneNumber));

                    }

                    phoneCursor.close();

                }

            }

        }

        cursor.close();

        loadingPB.setVisibility(View.GONE);

        contactRVAdapter.notifyDataSetChanged();

    }

}

import android.Manifest;

import android.content.DialogInterface;

import android.content.Intent;

import android.database.Cursor;

import android.net.Uri;

import android.os.Bundle;

import android.provider.ContactsContract;

import android.provider.Settings;

import android.view.Menu;

import android.view.MenuInflater;

import android.view.MenuItem;

import android.view.View;

import android.widget.ProgressBar;

import android.widget.SearchView;

import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;

import androidx.appcompat.app.AppCompatActivity;

import androidx.core.view.MenuItemCompat;

import androidx.recyclerview.widget.LinearLayoutManager;

import androidx.recyclerview.widget.RecyclerView;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import com.karumi.dexter.Dexter;

import com.karumi.dexter.MultiplePermissionsReport;

import com.karumi.dexter.PermissionToken;

import com.karumi.dexter.listener.DexterError;

import com.karumi.dexter.listener.PermissionRequest;

import com.karumi.dexter.listener.PermissionRequestErrorListener;

import com.karumi.dexter.listener.multi.MultiplePermissionsListener;

import java.util.ArrayList;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private ArrayList<ContactsModal> contactsModalArrayList;

    private RecyclerView contactRV;

    private ContactRVAdapter contactRVAdapter;

    private ProgressBar loadingPB;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        contactsModalArrayList = new ArrayList<>();

        contactRV = findViewById(R.id.idRVContacts);

        FloatingActionButton addNewContactFAB = findViewById(R.id.idFABadd);

        loadingPB = findViewById(R.id.idPBLoading);

        prepareContactRV();

        requestPermissions();

        addNewContactFAB.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                Intent i = new Intent(MainActivity.this, CreateNewContactActivity.class);

                startActivity(i);

            }

        });

    }

    @Override

    public boolean onCreateOptionsMenu(Menu menu) {

        MenuInflater inflater = getMenuInflater();

        inflater.inflate(R.menu.search_menu, menu);

        MenuItem searchViewItem = menu.findItem(R.id.app_bar_search);

        final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchViewItem);

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

            @Override

            public boolean onQueryTextSubmit(String query) {

                searchView.clearFocus();

                return false;

            }

            @Override

            public boolean onQueryTextChange(String newText) {

                filter(newText.toLowerCase());

                return false;

            }

        });

        return super.onCreateOptionsMenu(menu);

    }

    private void filter(String text) {

        ArrayList<ContactsModal> filteredlist = new ArrayList<>();

        for (ContactsModal item : contactsModalArrayList) {

            if (item.getUserName().toLowerCase().contains(text.toLowerCase())) {

                filteredlist.add(item);

            }

        }

        if (filteredlist.isEmpty()) {

            Toast.makeText(this, "No Contact Found", Toast.LENGTH_SHORT).show();

        } else {

            contactRVAdapter.filterList(filteredlist);

        }

    }

    private void prepareContactRV() {

        contactRVAdapter = new ContactRVAdapter(this, contactsModalArrayList);

        contactRV.setLayoutManager(new LinearLayoutManager(this));

        contactRV.setAdapter(contactRVAdapter);

    }

    private void requestPermissions() {

        Dexter.withActivity(this)

                .withPermissions(Manifest.permission.READ_CONTACTS,

                        Manifest.permission.CALL_PHONE,

                        Manifest.permission.SEND_SMS, Manifest.permission.WRITE_CONTACTS)

                .withListener(new MultiplePermissionsListener() {

                    @Override

                    public void onPermissionsChecked(MultiplePermissionsReport multiplePermissionsReport) {

                        if (multiplePermissionsReport.areAllPermissionsGranted()) {

                            getContacts();

                            Toast.makeText(MainActivity.this, "All the permissions are granted..", Toast.LENGTH_SHORT).show();

                        }

                        if (multiplePermissionsReport.isAnyPermissionPermanentlyDenied()) {

                            showSettingsDialog();

                        }

                    }

                    @Override

                    public void onPermissionRationaleShouldBeShown(List<PermissionRequest> list, PermissionToken permissionToken) {

                        permissionToken.continuePermissionRequest();

                    }

                }).withErrorListener(new PermissionRequestErrorListener() {

            @Override

            public void onError(DexterError error) {

                Toast.makeText(getApplicationContext(), "Error occurred! ", Toast.LENGTH_SHORT).show();

            }

        })

                .onSameThread().check();

    }

    private void showSettingsDialog() {

        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);

        builder.setTitle("Need Permissions");

        builder.setMessage("This app needs permission to use this feature. You can grant them in app settings.");

        builder.setPositiveButton("GOTO SETTINGS", new DialogInterface.OnClickListener() {

            @Override

            public void onClick(DialogInterface dialog, int which) {

                dialog.cancel();

                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);

                Uri uri = Uri.fromParts("package", getPackageName(), null);

                intent.setData(uri);

                startActivityForResult(intent, 101);

            }

        });

        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

            @Override

            public void onClick(DialogInterface dialog, int which) {

                dialog.cancel();

            }

        });

        builder.show();

    }

    private void getContacts() {

        String contactId = "";

        String displayName = "";

        Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");

        if (cursor.getCount() > 0) {

            while (cursor.moveToNext()) {

                int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));

                if (hasPhoneNumber > 0) {

                    contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));

                    displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

                    Cursor phoneCursor = getContentResolver().query(

                            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,

                            null,

                            ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",

                            new String[]{contactId},

                            null);

                    if (phoneCursor.moveToNext()) {

                        String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

                        contactsModalArrayList.add(new ContactsModal(displayName, phoneNumber));

                    }

                    phoneCursor.close();

                }

            }

        }

        cursor.close();

        loadingPB.setVisibility(View.GONE);

        contactRVAdapter.notifyDataSetChanged();

    }

}

0 / 0 / 0

Регистрация: 04.08.2013

Сообщений: 13

1

01.11.2014, 17:22. Показов 6079. Ответов 10


Стоит задача написать простой телефонный справочник, примерно 4к абонентов, но увы, мои познания в программирование под android скудны. Я понимаю, задача тривиальная, но все же.
Как я понял лучше использовать БД, а не массив? И как реализовать динамическую подгрузку контента и поиск? Спасибо!

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



1605 / 1337 / 291

Регистрация: 25.10.2009

Сообщений: 3,487

Записей в блоге: 2

01.11.2014, 18:50

2

Цитата
Сообщение от qwer1i
Посмотреть сообщение

мои познания в программирование под android скудны

насколько скудны?

Цитата
Сообщение от qwer1i
Посмотреть сообщение

Как я понял лучше использовать БД, а не массив?

Только БД.

Цитата
Сообщение от qwer1i
Посмотреть сообщение

И как реализовать динамическую подгрузку контента

Можно запросом с параметрами limit и offset.



1



0 / 0 / 0

Регистрация: 04.08.2013

Сообщений: 13

01.11.2014, 20:50

 [ТС]

3

Максимально скудны
Но, в принципе, я понял, в каком направлении рыть, спасибо.
А вы случайно не знаете готовых или полу готовых решений?



0



325 / 123 / 10

Регистрация: 01.11.2012

Сообщений: 586

01.11.2014, 23:44

4

Все решения кусковые, сразу готовых не найдете, т.к. определенных правил, как я уже убедился, не существует. Собирайте по мере надобности по кусочкам. Я начинал банально вывести данные из таблицы в листвью. Соответственно надо уметь хоть что то писать и понимать в SQL и учится делать кастомный адаптер. Все эти вещи есть тут на форуме.



1



14 / 14 / 3

Регистрация: 13.02.2012

Сообщений: 233

Записей в блоге: 1

07.03.2015, 10:25

5

qwer1i, нашел решение своей задачи? Тоже встала похожая задача.



0



420 / 357 / 47

Регистрация: 22.05.2013

Сообщений: 2,518

07.03.2015, 14:14

6

ИМХО 4к это слишком много записей! Будет тормозить! Норма (по моим наблюдениям) несколько (2-4) сотен!!!
Для большего нужна система оптимизации. Когда-то была описана на хабре — поищите там.

Я «для себя» пишу звонилку. У меня в книжке ~500~600 номеров (>10 лет копил) и если хочу вывести что-то больше чем 1-2 поля в одну строку (картинки, расчетные поля, у меня их уже больше 8ми), приходится оптимизировать…



0



325 / 123 / 10

Регистрация: 01.11.2012

Сообщений: 586

07.03.2015, 14:16

7

Tester64, тормозит из-за чего? Из-за получения данных из БД или при выводе в список?



0



420 / 357 / 47

Регистрация: 22.05.2013

Сообщений: 2,518

07.03.2015, 14:29

8

Получение почти мгновенное, хотя если столбцов в запросе много, может задуматься почти на секунду.
Проблема при ПОЗИЦИОНИРОВАНИИ в запросе.
Ведь как рисуется запись №300:
-встать на позицию в запросе
-получить из запроса нужные поля
-отрисовать полученное в строку

так вот встать на позицию занимает СЛИШКОМ долго для быстрого листания!

Один из хабравчанинов это решил общим запросом по индексу и скоростными запросами по каждому полю.



1



24 / 17 / 7

Регистрация: 05.12.2013

Сообщений: 70

07.03.2015, 22:48

9

Что-то запутоно, у меня есть опыт написания клиента для сервиса анонимных вопросов, ну так вот, выкачивал я и несколько тысячь вопросов — не тормозило (хранил в бд). Видимо у вас архитектура такова или многопоточностью не корректно воспользывались.



0



420 / 357 / 47

Регистрация: 22.05.2013

Сообщений: 2,518

08.03.2015, 11:26

10

Цитата
Сообщение от balolam
Посмотреть сообщение

выкачивал я и несколько тысячь вопросов

Вы их ОДНОВРЕМЕННО пытались вывести на экран? все несколько тысяч? Хранить в базе можно и миллионы. Но если хотите выводить на экран по быстрому, то возникают проблемы. Когда вы скролите быстрым методом (ползунком, а не слайд пальцем), то за один слайд на экран надо вывести за одну секунду десяток-сотню строк. Даже если каждую выводит 0.1 секунды, то тормоза ОЧЕНЬ наглядные.

Скажем так… у меня была база на 500-900 позиций. Надо было выводить 6-12 полей в одну строку (включая 3-4 картинки). Листвьюв справлялся. Но база выросла до 2500 и… тормоза! Вынужден переделывать адаптер.

Сейчас сделал свой спид-адаптер на основе хабра и своих идей. Его использую как предок для спид-адаптер-sqlite. В том числе и для адаптера показа списка контактов и истории звонков. Планирую еще ускорить на порядок через многопоточность. Уже добивался, но вынужден был отключить — не победил утечку памяти — не было инструментов отлова (тупо перегружалась мобилка через 10 минут тестов).



0



0 / 0 / 0

Регистрация: 16.07.2013

Сообщений: 51

08.03.2015, 12:32

11

Есть ли кто, кто разбирается в AIDE(android integrated development environment)?



0



Код который изменился «Справочник рыбака»

MainActivity.java

package com.neco_desarrollo.fisher_hanbook;

import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import androidx.core.view.GravityCompat;
import androidx.appcompat.app.ActionBarDrawerToggle;
import android.view.MenuItem;
import com.google.android.material.navigation.NavigationView;
import com.neco_desarrollo.fisher_hanbook.settings.SettingsActivity;
import com.neco_desarrollo.fisher_hanbook.utils.CustomArrayAdapter;
import com.neco_desarrollo.fisher_hanbook.utils.ListItemClass;

import androidx.drawerlayout.widget.DrawerLayout;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.Menu;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private ListView list;
private String[] array, arraySecName;
private CustomArrayAdapter adapter;
private Toolbar toolbar;
private int category_index;
private int[] array_fish_color = new int []{R.color.green_2, R.color.yellow, R.color.green_2, R.color.red,R.color.red};
private List<ListItemClass> listItemMain;
private ListItemClass listItem;









@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

list = findViewById(R.id.listView);
listItemMain = new ArrayList<>();

fillArray(R.string.fish,getResources().getStringArray(R.array.fish_array),getResources().getStringArray(R.array.fish_array_2),array_fish_color, 0);
adapter = new CustomArrayAdapter(this,R.layout.list_view_item_1,listItemMain,getLayoutInflater());
list.setAdapter(adapter);

DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
navigationView.setNavigationItemSelectedListener(this);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
Intent intent = new Intent(MainActivity.this,Text_Content_Activity.class);
intent.putExtra("category",category_index);
intent.putExtra("position",position);
startActivity(intent);

}
});


}

@Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
toolbar.setTitle(R.string.fish);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {

Intent i = new Intent(MainActivity.this, SettingsActivity.class);
startActivity(i);
}

return super.onOptionsItemSelected(item);
}

@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();

if (id == R.id.id_fish) {

fillArray(R.string.fish,getResources().getStringArray(R.array.fish_array),getResources().getStringArray(R.array.fish_array_2),array_fish_color, 0);
}
else if
(id == R.id.id_na)
{

}
else if (id == R.id.id_sna)
{

}
else if (id == R.id.id_pri)
{

}
else if (id == R.id.id_history)
{

}
else if (id == R.id.id_advice)
{

}

DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
private void fillArray(int title,String[] nameArray,String[] secName,int[] image,int index )
{

toolbar.setTitle(title);
if(adapter != null) adapter.clear();

for(int i = 0; i < nameArray.length; i++)
{
listItem = new ListItemClass();
listItem.setNameF(nameArray[i]);
listItem.setSecond_name(secName[i]);
listItem.setImage_id(image[i]);

listItemMain.add(listItem);
}
if(adapter != null) adapter.notifyDataSetChanged();
category_index = index;
}
}

ListItemClass.java

package com.neco_desarrollo.fisher_hanbook.utils;

public class ListItemClass {
String name;
String second_name;
int image_id;

public String getNameF() {
return name;
}

public void setNameF(String name) {
this.name = name;
}

public String getSecond_name() {
return second_name;
}

public void setSecond_name(String second_name) {
this.second_name = second_name;
}

public int getImage_id() {
return image_id;
}

public void setImage_id(int image_id) {
this.image_id = image_id;
}
}

CustomArrayAdapter.java

package com.neco_desarrollo.fisher_hanbook.utils;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.neco_desarrollo.fisher_hanbook.R;

import java.util.ArrayList;
import java.util.List;


public class CustomArrayAdapter extends ArrayAdapter<ListItemClass> {
private LayoutInflater inflater;
private List<ListItemClass> listItem = new ArrayList<>();
private Context context;


public CustomArrayAdapter(@NonNull Context context, int resource, List<ListItemClass> listItem,LayoutInflater inflater) {
super(context, resource, listItem);
this.inflater = inflater;
this.listItem = listItem;
this.context = context;

}

@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
ViewHolder viewHolder;
ListItemClass listItemMain = listItem.get(position);
if(convertView == null){
convertView = inflater.inflate(R.layout.list_view_item_1, null, false);
viewHolder = new ViewHolder();
viewHolder.image = convertView.findViewById(R.id.imItem);
viewHolder.name = convertView.findViewById(R.id.tvName);
viewHolder.secName = convertView.findViewById(R.id.tvSecName);
convertView.setTag(viewHolder);



}
else
{
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.name.setText(listItemMain.getNameF());
viewHolder.secName.setText(listItemMain.getSecond_name());
viewHolder.image.setImageResource(listItemMain.image_id);








return convertView;
}
private class ViewHolder{
TextView name;
TextView secName;
ImageView image;

}
}

arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="fish_array">
<item>Карп</item>
<item>Щука</item>
<item>Сом</item>
<item>Осетр</item>
<item>Налим</item>
</string-array>
<string-array name="fish_array_2">
<item>Карпиус</item>
<item>Щукариус</item>
<item>Сомариус</item>
<item>Осетрариус</item>
<item>Налимиус</item>
</string-array>

<string-array name="na_array">
<item>Червяк</item>
<item>Кукуруза</item>
<item>Хлеб</item>
<item>Рис</item>
</string-array>
<string-array name="sna_array">
<item>Грузила</item>
<item>Крючки</item>
<item>Леска</item>
<item>Блесна</item>
</string-array>
<string-array name="pri_array">
<item>Кукуруза</item>
<item>Хлеб</item>
<item>Рис</item>

</string-array>
<string-array name="history_array">
<item>Рыбак и море</item>
<item>Рыбак и щюка</item>
<item>На дону</item>
<item>Случай на рыбалке</item>

</string-array>
<string-array name="advice_array">
<item>Советы по прикормке</item>
<item>Сезон рыбалки</item>
<item>На что клюет</item>
<item>Большой улов</item>

</string-array>
<string-array name="main_text_size_array">
<item>Большой</item>
<item>Средний</item>
<item>Маленький</item>

</string-array>


</resources>

все остальные файлы без изменений. В файле arrays.xml добавляем если хотим свои собственные названия рыб и.т.д но помним если изменим название самого массива то нужно также поменять это в кодею 

Понравилась статья? Поделить с друзьями:

Не пропустите и эти статьи:

  • Как написать справку что не получал единовременное пособие на рождение ребенка
  • Как написать справку что болел орви
  • Как написать справку физруку про месячные
  • Как написать справку учителю физкультуры от родителей образец при месячных
  • Как написать справку учителю физкультуры об освобождении месячные

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии