Change view. Изменяем вид интерфейса

в 1:07, , рубрики: android, design, tutorial, интерфейсы, Разработка под android, метки: , ,

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

Итак, реализовывать мы это будем, используя LayoutInflater. На странице с паттерном в качестве примера приведен файловый менеджер с ListView и GridView. Вот их то мы и используем. Соответственно list.xml:

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/listLayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    
</ListView>

и grid.xml (в котором мы для пущей красоты сделаем 4 столбика и выставим gravity на center):

<GridView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/gridLayout"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:numColumns="4"
        android:gravity="center" >

</GridView>

Ах да, ещё отдельно сделаем объекты для наших View, чтобы максимально упростить себе жизнь. Итак, list_item.xml:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/linearLayout1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_launcher" />

        <TextView
            android:id="@+id/textItem"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Medium Text"
            android:textAppearance="?android:attr/textAppearanceMedium" />

    </LinearLayout>

и grid_item.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <Button
        android:id="@+id/gridButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        android:drawableTop="@drawable/ic_launcher" />

</LinearLayout>

Ну теперь можно приступать к Activity (main.xml трогать не будем). Раз уж мы используем паттерны дизайна, то стараемся уважать пользователей нашего приложения, а соответственно надо запоминать их выбор, чтобы не приходилось настраивать интерфейс при каждом входе. Для этого используем SharedPreferences и сделаем два метода:

private void SavePreferences(String key, String value) {
	    SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
	    SharedPreferences.Editor editor = sharedPreferences.edit();
	    editor.putString(key, value);
	    editor.commit();
	}

private String LoadPreferences(String key) {
	    SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
	    String loadedString = sharedPreferences.getString(key, "list");	    
	    return loadedString;
	}

Теперь нужно создать ViewGroup, который будет хранить наши View (да и сами View неплохо было бы создать; можно было бы написать «Виды», но мне жутко не нравится, когда переводят подобные термины, поэтому лучше уж я напишу на английском). Отдельный объект для LayoutInflater мы создавать не будем, так как документация по андроиду нам не рекомендует этого делать (обосновывая это тем, что в контексте нашего Activity он уже создан и правильно сконфигурирован, то есть остаётся только получить instance). Соответственно такой кот мы поместим в метод onCreate:

        setContentView(R.layout.main);
        
        content = new String[] {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Item 10"};
        
        viewGroup = (ViewGroup) findViewById(R.id.mainLayout);        
        list =  getLayoutInflater().inflate(R.layout.list, null);       
    	grid = getLayoutInflater().inflate(R.layout.grid, null);
    	
        
        if(LoadPreferences("VIEW").equalsIgnoreCase("list"))
        	setList();
        else
        	setGrid(); 

А теперь расскажем про setList() и setGrid(). Так как нам в дальнейшем предстоит динамически обновлять наш интерфейс, то я создал отдельные методы для этого:

private void setList()
    {
    	viewGroup.removeAllViews();
    	viewGroup.addView(list); 
        ListView listView = (ListView) list.findViewById(R.id.listLayout);
    	listView.setAdapter(new ArrayAdapter<String>(this, R.layout.list_item, R.id.textItem, content));
    }
    
private void setGrid()
    {
    	viewGroup.removeAllViews();
    	viewGroup.addView(grid);
    	GridView gridview = (GridView) findViewById(R.id.gridLayout);
        gridview.setAdapter(new ArrayAdapter<String>(this, R.layout.grid_item, R.id.gridButton, content));
    }

Здорово! Можно попробовать запустить приложение! Оно работает! Но неплохо было бы теперь добавить переключалку, ради которой, собственно, и писалась статья. Сделаем это через меню, которое вызывается при нажатии хардварной кнопки. Так выдлядит menu.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@+id/item" android:title="Change view"></item>  
</menu>

А так методы для его работы в нашем Activity (оба метода возвращают true, вместо выполнения операций суперкласса, так как мы определили свой интерфейс и задали свои собственные действия):

        @Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		MenuInflater inflater = getMenuInflater();
                inflater.inflate(R.menu.menu, menu);
                return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		if(LoadPreferences("VIEW").equalsIgnoreCase("list"))
		{
			setGrid();
            SavePreferences("VIEW", "grid");
		}
		else
		{
			setList();
            SavePreferences("VIEW", "list");
		}
		
		return true;
	}

Ну вот вроде и всё. На всякий случай выложу проект в архиве. И удачи начинающим андроид-разработчикам.

Автор: daniilmann


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js