Android рдЕрдиреБрднрд╛рдЧ рд╕реВрдЪреА

рд╕рд┐рд╕реНрдЯрдо рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдФрд░ рдерд░реНрдб-рдкрд╛рд░реНрдЯреА рджреЛрдиреЛрдВ рдореЗрдВ рд╡рд░реНрдЧреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рд╕реВрдЪрд┐рдпрд╛рдБ рдХрд╛рдлреА рд╕рд╛рдорд╛рдиреНрдп рд╣реИрдВред рд▓реЗрдХрд┐рди, рдЕрдЬреАрдм рддрд░рд╣ рд╕реЗ, рдордВрдЪ рдЖрдИрдУрдПрд╕ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЙрдиреНрд╣реЗрдВ рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреА рдкреЗрд╢рдХрд╢ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
рдЫрд╡рд┐

рдореБрдЭреЗ рд╕реВрдЪреА рд╢реАрд░реНрд╖рд▓реЗрдЦреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рджреЛ рддрд░реАрдХреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рд╣реИ:

рдкрд╣рд▓рд╛ рддрд░реАрдХрд╛ рдХреЛрдб рд▓рд┐рдЦрдирд╛ рдЖрд╕рд╛рди рд╣реИ: рд╕реВрдЪреА рд╕реЗрд▓ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдЪреБрдирдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд▓реЗрдХрд┐рди рдкреНрд░рджрд░реНрд╢рди, рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЕрдзрд┐рдХ "рдореБрд╢реНрдХрд┐рд▓" рд╣реИред рджреВрд╕рд░рд╛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдмреЛрдЭрд┐рд▓ рд╣реИ, рд▓реЗрдХрд┐рди рдереЛрдбрд╝рд╛ рддреЗрдЬ рдФрд░, рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд, рдЖрдкрдХреЛ рд╕рд┐рд╕реНрдЯрдо рд▓реЗрдЖрдЙрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдпрд╣ рд▓реЗрдЦ рджреВрд╕рд░реЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред

рдПрдбрд╛рдкреНрдЯрд░ рдмреЗрд╕ рдХреНрд▓рд╛рд╕

рдЖрдзрд╛рд░ рд▓рд╛рдЗрдирд░ рд╕реВрдЪреА рд▓рд╛рдЗрди рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЬрд┐рдореНрдореЗрджрд╛рд░реА рд▓реЗрддрд╛ рд╣реИ, рдмрджрд▓реЗ рдореЗрдВ рдЕрдкрдиреЗ рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░рд┐рдпреЛрдВ рдХреЛ рд╣реЗрдбрд░ рдФрд░ рдбреЗрдЯрд╛ рд▓рд╛рдЗрди рдмрдирд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рддрд╛ рд╣реИ:

protected abstract int getSectionsCount( ); protected abstract int getRowsCountInSection( int section ); protected abstract View getHeaderView( int section, View convertView, ViewGroup parent, LayoutInflater inflater ); protected abstract View getItemView( int section, int row, View convertView, ViewGroup parent, LayoutInflater inflater ); 


рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЬрдм рд╕реВрдЪреА рдореЗрдВ рдбреЗрдЯрд╛ рдмрджрд▓рддреЗ рд╣реИрдВ (рдЬрдм InformDataSetChanged рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ), рд╣рдо рд╕реВрдЪреА рдореЗрдВ рдХреБрд▓ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рддрддреНрд╡реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХреИрд╢ рдХрд░рддреЗ рд╣реИрдВ, рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреА рд╕реВрдЪреА рд▓рд╛рдЗрдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдФрд░ рдЗрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рдВрдмрдВрдзреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рддреЗ рд╣реИрдВ:
  private void setupAdapter( ) { int sectionsCount = getSectionsCount(); _rowsCountsInSections = new int [sectionsCount]; _viewTypes = new int [sectionsCount]; _totalRowsCount = sectionsCount; Set<Integer> viewTypesSet = new HashSet<Integer>(); for (int i = 0; i < sectionsCount; i++) { _rowsCountsInSections[i] = getRowsCountInSection(i); _totalRowsCount += _rowsCountsInSections[i]; _viewTypes[i] = getViewTypeForSection(i); viewTypesSet.add(_viewTypes[i]); } viewTypesSet.add(VIEW_TYPE_HEADER); _viewTypesCount = viewTypesSet.size(); } 


рдПрдХрддреНрд░рд┐рдд рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рд╣рдо рдЖрд╕рд╛рдиреА рд╕реЗ рдЪреБрди рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдореЗрдВ getView рдореЗрдВ рдХреНрдпрд╛ рдмрдирд╛рдирд╛ рд╣реИ:
  @Override final public View getView( int position, View convertView, ViewGroup parent ) { int section = getItemSection(position); if (isItemHeader(position)) return getHeaderView(section, convertView, parent, _inflater); int rowInSection = getItemRowInSection(position); return getItemView(section, rowInSection, convertView, parent, _inflater); } 


рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ рдХрд┐ рдХреНрдпрд╛ рд▓рд╛рдЗрди рд╣реЗрдбрд░ рдпрд╛ рд╕реЗрдХреНрд╢рди рдПрд▓реАрдореЗрдВрдЯ рд╣реИ, рдЬреИрд╕реЗ:
  private boolean isItemHeader( int position ) { int sum = 0; for (int i = 0; i < _rowsCountsInSections.length && sum <= position; i++) { if (sum == position) return true; sum += _rowsCountsInSections[i] + 1; } return false; } private int getItemSection( int position ) { int sum = 0; int section = 0; while (sum <= position && section < _rowsCountsInSections.length) sum += _rowsCountsInSections[section++] + 1; return section - 1; } private int getItemRowInSection( int position ) { int section = getItemSection(position); int sum = 0; for (int i = 0; i < section; i++) sum += _rowsCountsInSections[i] + 1; return position - sum - 1; } 

рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдЕрдиреБрднрд╛рдЧ рдХреЗ рдЕрдВрджрд░ рдЕрдиреБрднрд╛рдЧ рд╕рдВрдЦреНрдпрд╛ рдФрд░ рд╕реВрдЪрдХрд╛рдВрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЛ рдПрдХ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЕрд▓рдЧрд╛рд╡ рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рдкреВрд░реА рддрд░рд╣ рд╕реЗ:
 abstract public class BaseSectionedListAdapter extends BaseAdapter { private static int VIEW_TYPE_HEADER = 0; protected static int VIEW_TYPE_DATA = 1; final private LayoutInflater _inflater; private int _totalRowsCount = -1; private int [] _rowsCountsInSections; private int [] _viewTypes; private int _viewTypesCount; public BaseSectionedListAdapter( Context context ) { _inflater = LayoutInflater.from(context); } @Override final public int getCount( ) { if (_totalRowsCount == -1) setupAdapter(); return _totalRowsCount; } @Override final public Object getItem( int position ) { return null; } @Override final public long getItemId( int position ) { return position; } @Override final public View getView( int position, View convertView, ViewGroup parent ) { int section = getItemSection(position); if (isItemHeader(position)) return getHeaderView(section, convertView, parent, _inflater); int rowInSection = getItemRowInSection(position); return getItemView(section, rowInSection, convertView, parent, _inflater); } @Override public int getItemViewType( int position ) { if (isItemHeader(position)) return VIEW_TYPE_HEADER; int section = getItemSection(position); return _viewTypes[section]; } @Override public int getViewTypeCount( ) { return _viewTypesCount; } @Override public boolean isEnabled( int position ) { return !isItemHeader(position); } @Override final public boolean areAllItemsEnabled( ) { return false; } @Override final public void notifyDataSetChanged( ) { super.notifyDataSetChanged(); setupAdapter(); } @Override public boolean hasStableIds( ) { return true; } private boolean isItemHeader( int position ) { int sum = 0; for (int i = 0; i < _rowsCountsInSections.length && sum <= position; i++) { if (sum == position) return true; sum += _rowsCountsInSections[i] + 1; } return false; } private int getItemSection( int position ) { int sum = 0; int section = 0; while (sum <= position && section < _rowsCountsInSections.length) sum += _rowsCountsInSections[section++] + 1; return section - 1; } private int getItemRowInSection( int position ) { int section = getItemSection(position); int sum = 0; for (int i = 0; i < section; i++) sum += _rowsCountsInSections[i] + 1; return position - sum - 1; } private void setupAdapter( ) { int sectionsCount = getSectionsCount(); _rowsCountsInSections = new int [sectionsCount]; _viewTypes = new int [sectionsCount]; _totalRowsCount = sectionsCount; Set<Integer> viewTypesSet = new HashSet<Integer>(); for (int i = 0; i < sectionsCount; i++) { _rowsCountsInSections[i] = getRowsCountInSection(i); _totalRowsCount += _rowsCountsInSections[i]; _viewTypes[i] = getViewTypeForSection(i); viewTypesSet.add(_viewTypes[i]); } viewTypesSet.add(VIEW_TYPE_HEADER); _viewTypesCount = viewTypesSet.size(); } protected int getViewTypeForSection( int section ) { return VIEW_TYPE_DATA; } protected abstract int getSectionsCount( ); protected abstract int getRowsCountInSection( int section ); protected abstract View getHeaderView( int section, View convertView, ViewGroup parent, LayoutInflater inflater ); protected abstract View getItemView( int section, int row, View convertView, ViewGroup parent, LayoutInflater inflater ); } 


рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ

рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг: рд╣рдо рдкреНрд░рд╡реЗрд╢ рдкрд░ "рд╡рд░реНрдЧреЛрдВ" рдХреА рдПрдХ рд╕реВрдЪреА рджрд░реНрдЬ рдХрд░рддреЗ рд╣реИрдВ, рдЕрдиреБрднрд╛рдЧреЛрдВ рд╕реЗ рд╕рднреА рдбреЗрдЯрд╛ рдХреЛ рдПрдХ рд╢реИрд▓реА рдореЗрдВ рдЦреАрдВрдЪрддреЗ рд╣реИрдВред
рдЕрдиреБрднрд╛рдЧ рд╢реАрд░реНрд╖ рд▓реЗрдЦ рдФрд░ рдбреЗрдЯрд╛ рд╕реЗрдЯ рдХрд╛ рд╢реАрд░реНрд╖рдХ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИ:
 final public class SimpleSection { final private String _title; final private List<?> _data; public SimpleSection( String title, List<?> data ) { _title = title; _data = data; } public String getTitle( ) { return _title; } public List<?> getData( ) { return _data; } } 


рд╢реАрд░реНрд╖рдХ рдПрдХ TextView рд╕реЗ рдорд┐рд▓рдХрд░ рд╕рдмрд╕реЗ рд╕рд░рд▓ рд▓реЗрдЖрдЙрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ:
 <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="30dp" android:textAppearance="?android:attr/textAppearanceSmallInverse" android:gravity="center_vertical" android:paddingLeft="6dip" android:background="@android:color/black" /> 


рдЕрдкрдиреА рд╕рдВрдкреВрд░реНрдгрддрд╛ рдореЗрдВ рд╕рд░рд▓ рдПрдбрд╛рдкреНрдЯрд░:

 final public class SimpleSectionedListAdapter extends BaseSectionedListAdapter { final private List<SimpleSection> _sections; public SimpleSectionedListAdapter( Context context, List<SimpleSection> sections ) { super(context); _sections = sections; } @Override protected int getSectionsCount( ) { return _sections.size(); } @Override protected int getRowsCountInSection( int section ) { return _sections.get(section).getData().size(); } @Override protected View getHeaderView( int section, View convertView, ViewGroup parent, LayoutInflater inflater ) { if (convertView == null) convertView = inflater.inflate(R.layout.list_header, parent, false); TextView text = (TextView)convertView; text.setText(_sections.get(section).getTitle()); return convertView; } protected Object getItemInSection( int section, int row ) { return _sections.get(section).getData().get(row); } @Override protected View getItemView( int section, int row, View convertView, ViewGroup parent, LayoutInflater inflater ) { Object item = getItemInSection(section, row); if (convertView == null) convertView = inflater.inflate(android.R.layout.simple_list_item_1, parent, false); TextView text = (TextView)convertView; text.setText(item.toString()); return convertView; } } 


рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░

рдпрджрд┐ рдЖрдк рдКрдкрд░ рджрд┐рдП рдЧрдП рдПрдбреЙрдкреНрдЯрд░ рдкрд░ рдХреБрдЫ рдбреЗрдЯрд╛ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдХреБрдЫ рд╕рдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдпрджрд┐ рдЖрдк getViewTypeForSection рдХреЗ рд╕рд╛рде рдЦреЗрд▓рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ рджреВрд╕рд░реА рддрд╕реНрд╡реАрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ):
рдЫрд╡рд┐рдЫрд╡рд┐

рдХреЛрдбрд┐рдВрдЧ рд╢реИрд▓реА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреЛрдИ рднреА рдЯрд┐рдкреНрдкрдгреА, рд╕реБрдЭрд╛рд╡ рдФрд░ рд╢рд╛рдк рд╕реНрд╡рд╛рдЧрдд рдпреЛрдЧреНрдп рд╣реИред

Source: https://habr.com/ru/post/In150615/


All Articles