There is an ExpandableListView drop-down list where countries and their attractions are displayed. Headings are countries, when you click on a country, a drop-down list opens with attractions.

How to make a custom look for these drop-down items themselves.

Created markup for each item from dropdown list

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="5dp"> <de.hdodenhof.circleimageview.CircleImageView xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/img" android:src="@drawable/bg" app:civ_border_color="#FF000000" android:layout_width="42dp" android:layout_height="42dp" android:scaleType="centerCrop" /> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:paddingLeft="8dp" android:paddingRight="8dp"> <TextView android:text="" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/txtTitle" android:layout_weight="1" android:gravity="left|center" /> <TextView android:text="" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/txtHistory" android:layout_weight="1" android:singleLine="true" /> </LinearLayout> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@drawable/icon_star_outline_black" android:id="@+id/btnfavorite" android:background="@drawable/white_button" android:focusable="false" android:onClick="onFavoriteClick" /> </LinearLayout> </LinearLayout> 

Class dbhelper

 public class DBHeler extends SQLiteOpenHelper { private static String DB_PATH; private static final String DATABASE_NAME = "mydb.db"; private static final int DATABASE_VERSION = 1; public SQLiteDatabase database; private Context myContext; public DBHeler(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); this.myContext = context; try { //ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΏΡƒΡ‚ΡŒ Π΄ΠΎ Π‘Π” вмСстС с ΠΈΠΌΠ΅Π½Π΅ΠΌ. DB_PATH = myContext.getDatabasePath(DATABASE_NAME).toString(); createDataBase(); openDataBase(); } catch (IOException e) { e.printStackTrace(); } } public Cursor getCategoryData() { return this.getReadableDatabase().query(Contract.Entry.TABLE_COUNTRY, null, null, null, null, null, null); } public Cursor getSubCategoryData(long categoryID) { return this.getReadableDatabase().query(Contract.Entry.TABLE_DOST, null, Contract.Entry._ID + " = " + categoryID, null, null, null, null); } public void createDataBase() throws IOException { boolean dbExist = checkDataBase(); if (!dbExist) { this.getReadableDatabase(); try { copyDataBase(); } catch (IOException e) { throw new Error("Error copying database"); } } } private boolean checkDataBase(){ SQLiteDatabase checkDB = null; try { checkDB = SQLiteDatabase.openDatabase(DB_PATH, null, SQLiteDatabase.OPEN_READONLY); } catch (SQLiteException e) { // Π±Π°Π·Π° Π½Π΅ сущСствуСт } if (checkDB != null) { checkDB.close(); } return checkDB != null; } private void copyDataBase() throws IOException { InputStream myInput = myContext.getAssets().open(DATABASE_NAME); String outFileName = DB_PATH; OutputStream myOutput = new FileOutputStream(outFileName); byte[] buffer = new byte[1024]; int length; while ((length = myInput.read(buffer))>0){ myOutput.write(buffer, 0, length); } myOutput.flush(); myOutput.close(); myInput.close(); } public void openDataBase() throws SQLException { database = SQLiteDatabase.openDatabase(DB_PATH, null, SQLiteDatabase.OPEN_READWRITE); } @Override public synchronized void close() { if(database != null) database.close(); super.close(); } @Override public void onCreate(SQLiteDatabase db) { } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } } 

Class MainActivity

 public class MainActivity extends AppCompatActivity { ExpandableListView elvMain; DBHeler db; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); db = new DBHeler(this); Cursor categoryData = db.getCategoryData(); startManagingCursor(categoryData); String[] groupFrom = { Contract.Entry.COLUMN_NAME }; int[] groupTo = { android.R.id.text1 }; String[] childFrom = { Contract.Entry.COLUMN_NAME }; int[] childTo = { android.R.id.text1 }; SimpleCursorTreeAdapter sctAdapter = new MyAdapter(this, categoryData, android.R.layout.simple_expandable_list_item_1, groupFrom, groupTo, android.R.layout.simple_list_item_1, childFrom, childTo); elvMain = (ExpandableListView) findViewById(R.id.list); elvMain.setAdapter(sctAdapter); } public class MyAdapter extends SimpleCursorTreeAdapter { public MyAdapter(Context context, Cursor cursor, int groupLayout, String[] groupFrom, int[] groupTo, int childLayout, String[] childFrom, int[] childTo) { super(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childFrom, childTo); } protected Cursor getChildrenCursor(Cursor groupCursor) { int idColumn = groupCursor.getColumnIndex(Contract.Entry._ID); return db.getSubCategoryData(groupCursor.getInt(idColumn)); } } } 

Contract class describing fields and column names

 public class Contract { private Contract() { }; public static final class Entry implements BaseColumns { public final static String TABLE_DOST = "dost"; public final static String TABLE_COUNTRY = "country"; public final static String _ID = BaseColumns._ID; public final static String COLUMN_NAME = "name"; public final static String COLUMN_OTHER = "other"; public final static String COLUMN_HISTORY = "history"; public final static String COLUMN_IMAGE = "image"; public final static String COLUMN_COUNTRY = "name"; public final static String COLUMN_COUNTRYID = "countryid"; public final static String COLUMN_FAVORITES = "favorites"; } } 

enter image description here enter image description here

  • What does the image field in the database contain? - pavlofff
  • there is the name of the picture in English, just a line that will be taken from the assets or raw folder without a difference. Finally, the extension .jpg is added to the end - Veronica

1 answer 1

In order to make a custom view for items of the drop-down list based on the SimpleCursorTreeAdapter you need to override the following methods in the adapter:

  • bindGroupView() - for own view of root items
  • bindChildView() - for own view of items in the drop-down list

These methods link widgets on the markup with the cursor data.

The markup itself is specified through the constructor when creating the adapter:

  • groupLayout - a link of the form R.layout.item for marking the root item
  • childLayout - link to the drop-down markup

Further, the adapter itself, since you do not need to change the appearance of root items, we restrict ourselves to nested ones. In the bindChildView() method, we find the widgets in the markup passed to the adapter and place in them the relevant data from the cursor, also passed to the method and already positioned on the desired line:

 public class MyAdapter extends SimpleCursorTreeAdapter { public MyAdapter(Context context, Cursor cursor, int groupLayout, String[] groupFrom, int[] groupTo, int childLayout, String[] childFrom, int[] childTo) { super(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childFrom, childTo); } protected Cursor getChildrenCursor(Cursor groupCursor) { int idColumn = groupCursor.getColumnIndex(Contract.Entry._ID); return db.getSubCategoryData(groupCursor.getInt(idColumn)); } @Override protected void bindChildView(View view, Context context, Cursor cursor, boolean isLastChild) { TextView title = (TextView)view.findViewById(R.id.txtTitle); title.setText(cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_NAME))); TextView history = (TextView)view.findViewById(R.id.txtHistory); history.setText(cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_HISTORY))); ImageButton favorite = (ImageButton) view.findViewById(R.id.btnFavorite); String fav = cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_FAVORITES)); if (fav.equals("Π² ΠΈΠ·Π±Ρ€Π°Π½Π½ΠΎΠΌ") { favorite.setImageResources(R.id.favorites); } else { favorite.setImageResources(R.id.not_favorites); } favorite.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠΈΠ·Π±Ρ€Π°Π½Π½ΠΎΠ³ΠΎ } }); CircleImageView image = (CircleImageView)view.findViewById(R.id.img); name_img = cursor.getString(Cursor.getColumnIndex(Contract.Entry.COLUMN_IMAGE))); // Π΄Π°Π»Π΅Π΅ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ name_img Π΅Π΅ самой } } 

When creating an adapter instance in activit, we specify instead of system markup, our own, for drop-down list items (the sixth constructor parameter), for example, let's call it my_item_list.xml :

 MyAdapter sctAdapter = new MyAdapter( this, categoryData, android.R.layout.simple_expandable_list_item_1, // Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠ° ΠΊΠΎΡ€Π½Π΅Π²Ρ‹Ρ… Π°ΠΉΡ‚Π΅ΠΌΠΎΠ² groupFrom, groupTo, R.layout.my_list_item, // Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠ° Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… Π°ΠΉΡ‚Π΅ΠΌΠΎΠ² childFrom, childTo); 

If necessary, the same is done for root items.

  • Plus from the moderator for the fact that you delete unnecessary more comments. Seriously, almost no one does, but in vain. )) - Nick Volynkin ♦