导依赖
implementation 'com.android.support:design:28.0.0'
MainActivity
public class MainActivity extends AppCompatActivity {
private ViewPager viewPager;
private TabLayout tabLayout;
private DrawerLayout drawerLayout;
private ActionBar actionBar;
private ActionBarDrawerToggle toggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState==null){
getSupportFragmentManager().beginTransaction()
.add(R.id.leftfragment,new LeftFragment())
.commit();
}
drawerLayout=findViewById(R.id.draw);
actionBar=getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
toggle=new ActionBarDrawerToggle(this,drawerLayout,R.string.start,R.string.end);
toggle.syncState();
drawerLayout.addDrawerListener(toggle);
viewPager=findViewById(R.id.p_viewpager);
tabLayout=findViewById(R.id.tab_bottom);
viewPager.setAdapter(new PViewAdapter(getSupportFragmentManager()));
tabLayout.setupWithViewPager(viewPager);
}
public void showPage(int viewpager){
viewPager.setCurrentItem(viewpager);
drawerLayout.closeDrawer(Gravity.START);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(toggle.onOptionsItemSelected(item)){
return true;
}
return super.onOptionsItemSelected(item);
}
}
外面的viewpager适配器
public class PViewAdapter extends FragmentPagerAdapter {
private String[] p_menus=new String[]{"首页","电影","我的"};
public PViewAdapter(FragmentManager fm) {
super(fm);
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return p_menus[position];
}
@Override
public Fragment getItem(int i) {
switch (i){
case 0:return new OneFragment();
case 1:return new TwoFragment();
default:return new ThreeFragment();
}
}
@Override
public int getCount() {
return p_menus.length;
}
}
LeftFragment侧边栏
public class LeftFragment extends Fragment {
private ListView listView;
private View view;
private List<String> list;
private Uri uri;
private LeftAdapter adapter;
public LeftFragment() {
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.left_fragment, container, false);
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
listView=view.findViewById(R.id.listviews);
list=new ArrayList<>();
list.add("首页");
list.add("电影");
list.add("消息");
adapter = new LeftAdapter(list,getContext());
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(position==0){
Intent intent=new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent,200);
}else{
((MainActivity)getActivity()).showPage(position-1);
}
}
});
}
private String url2Path(Uri uri) {
String[] proj = {MediaStore.Images.Media.DATA};
CursorLoader loader = new CursorLoader(getActivity(), uri, proj, null, null, null);
Cursor cursor = loader.loadInBackground();
int columnIndexOrThrow = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(columnIndexOrThrow);
}
private void progressImage(String imagePath) {
int size = getResources().getDimensionPixelSize(R.dimen.left_icon);
Bitmap bitmap = BitmapUtil.scaleBitmap(imagePath, size, size);
adapter.setBitmap(bitmap);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==200&&resultCode==getActivity().RESULT_OK){
uri=data.getData();
progressImage(url2Path(uri));
}
}
}
侧边栏的适配器(不规范)
public class LeftAdapter extends BaseAdapter {
private List<String> list;
private Context context;
private Bitmap bitmap;
public LeftAdapter(List<String> list, Context context) {
this.list = list;
this.context = context;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
notifyDataSetChanged();
}
@Override
public int getCount() {
return hasImage()?list.size()+1:list.size();
}
public boolean hasImage(){
return true;
}
@Override
public String getItem(int position) {
return list.get(position-1);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(hasImage()&&position==0){
IViewHolder holder;
if(convertView==null){
holder=new IViewHolder();
convertView=LayoutInflater.from(context).inflate(R.layout.left_image,parent,false);
holder.imageView=convertView.findViewById(R.id.image);
convertView.setTag(holder);
}else{
holder= (IViewHolder) convertView.getTag();
}
holder.imageView.setImageResource(R.mipmap.ic_launcher);
if(bitmap!=null){
holder.imageView.setImageBitmap(bitmap);
}
}else{
ViewHolder holder;
if(convertView==null){
holder=new ViewHolder();
convertView=LayoutInflater.from(context).inflate(R.layout.left_text,parent,false);
holder.textView=convertView.findViewById(R.id.text);
convertView.setTag(holder);
}else{
holder= (ViewHolder) convertView.getTag();
}
holder.textView.setText(getItem(position));
}
return convertView;
}
class IViewHolder{
ImageView imageView;
}
class ViewHolder{
TextView textView;
}
}
首页页面
public class OneFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
TextView textView=new TextView(getContext());
textView.setText("首页");
return textView;
}
}
我的页面
public class ThreeFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
TextView textView = new TextView(getContext());
textView.setText("我的");
return textView;
}
}
电影页面
public class TwoFragment extends Fragment {
private ViewPager viewPager;
private TabLayout tabLayout;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.two, container, false);
viewPager=view.findViewById(R.id.c_viewpager);
tabLayout=view.findViewById(R.id.tab_top);
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
viewPager.setAdapter(new CViewAdpater(getChildFragmentManager()));
tabLayout.setupWithViewPager(viewPager);
}
}
里面的Viewpager适配器
public class CViewAdpater extends FragmentPagerAdapter {
private String[] c_menus=new String[]{"正在上映","即将上映"};
public CViewAdpater(FragmentManager fm) {
super(fm);
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return c_menus[position];
}
@Override
public Fragment getItem(int i) {
switch (i){
case 0:return new ZFragment();
case 1:return new JFragment();
default:return null;
}
}
@Override
public int getCount() {
return c_menus.length;
}
}
正在上映页面
public class ZFragment extends Fragment {
private PullToRefreshListView listView;
private int mpage=1;
private PulAdapter adapter;
private SqliteDao dao;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.zheng, container, false);
listView=view.findViewById(R.id.pull_to_z);
adapter=new PulAdapter(getActivity());
dao=new SqliteDao(getContext());
listView.setAdapter(adapter);
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//同时支持刷新 加载
listView.setMode(PullToRefreshBase.Mode.BOTH);
listView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() {
@Override
public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {
mpage=1;
initData();
}
@Override
public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {
//mpage++;
initData();
}
});
initData();
}
private String url = "http://172.17.8.100/movieApi/movie/v1/findHotMovieList?count=10&page=";
private void initData() {
boolean b = NetUtil.getIntance().hasNetwork(getContext());
if(b){
NetUtil.getIntance().requestData(url + mpage, ContentBean.class, new NetUtil.CallBack<ContentBean>() {
@Override
public void onsuccess(ContentBean contentBean) {
if(mpage==1){
dao.del(1);
dao.addAll(1,contentBean.getResult());
/*Cursor cursor = dao.sel(1);
while (cursor.moveToNext()){
}*/
adapter.setPlist(contentBean.getResult());
}else{
dao.addAll(1,contentBean.getResult());
adapter.addPlist(contentBean.getResult());
}
mpage++;
listView.onRefreshComplete();
if(contentBean.getResult().size()<10){
listView.setMode(PullToRefreshBase.Mode.PULL_FROM_START);
}else{
listView.setMode(PullToRefreshBase.Mode.BOTH);
}
}
});
}
}
}
即将上映
public class JFragment extends Fragment {
private PullToRefreshListView listView;
private PulAdapter adapter;
private int mpage=1;
private SqliteDao dao;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.zheng, container, false);
listView=view.findViewById(R.id.pull_to_z);
adapter=new PulAdapter(getContext());
dao=new SqliteDao(getContext());
listView.setAdapter(adapter);
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//同时支持刷新 加载
listView.setMode(PullToRefreshBase.Mode.BOTH);
listView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() {
@Override
public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {
mpage=1;
initData();
}
@Override
public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {
//mpage++;
initData();
}
});
initData();
}
private String url = "http://172.17.8.100/movieApi/movie/v1/findReleaseMovieList?count=10&page=";
private void initData() {
boolean b = NetUtil.getIntance().hasNetwork(getContext());
if(b){
NetUtil.getIntance().requestData(url + mpage, ContentBean.class, new NetUtil.CallBack<ContentBean>() {
@Override
public void onsuccess(ContentBean contentBean) {
if(mpage ==1){
dao.del(2);
dao.addAll(2,contentBean.getResult());
adapter.setPlist(contentBean.getResult());
}else{
dao.addAll(2,contentBean.getResult());
adapter.addPlist(contentBean.getResult());
}
mpage++;
listView.onRefreshComplete();
if(contentBean.getResult().size()<10){
listView.setMode(PullToRefreshBase.Mode.PULL_FROM_START);
}else{
listView.setMode(PullToRefreshBase.Mode.BOTH);
}
}
});
}
}
}
正在上映和即将上映适配器
public class PulAdapter extends BaseAdapter {
private List<ContentBean.ResultBean> plist;
private Context context;
public PulAdapter(Context context) {
this.context = context;
plist=new ArrayList<>();
}
public void setPlist(List<ContentBean.ResultBean> list) {
plist.clear();
plist .addAll(list);
notifyDataSetChanged();
}
public void addPlist(List<ContentBean.ResultBean> data) {
plist.addAll(data);
notifyDataSetChanged();
}
@Override
public int getCount() {
return plist.size();
}
@Override
public ContentBean.ResultBean getItem(int position) {
return plist.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView==null){
convertView=LayoutInflater.from(context).inflate(R.layout.z_item,parent,false);
holder=new ViewHolder();
holder.image=convertView.findViewById(R.id.image);
holder.title=convertView.findViewById(R.id.title);
holder.summary=convertView.findViewById(R.id.summary);
convertView.setTag(holder);
}else{
holder= (ViewHolder) convertView.getTag();
}
holder.title.setText(getItem(position).getName());
holder.summary.setText(getItem(position).getSummary());
ImageLoader.getInstance().displayImage(getItem(position).getImageUrl(),holder.image);
return convertView;
}
class ViewHolder{
ImageView image;
TextView title,summary;
}
}
数据库创建
public class SqliteHelp extends SQLiteOpenHelper {
public SqliteHelp(Context context) {
super(context, "User.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table movie1(id integer primary key autoincrement," +
"type integer,"+
"name text," +
"summary text," +
"image_url text)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
数据库数据的修改
public class SqliteDao {
private static SqliteDao dao;
private SqliteHelp sqliteHelp;
private SQLiteDatabase database;
public SqliteDao(Context context) {
sqliteHelp=new SqliteHelp(context);
database=sqliteHelp.getWritableDatabase();
}
public static SqliteDao getIntance(Context context){
if(dao==null){
dao=new SqliteDao(context);
}
return dao;
}
public void add(int type, ContentBean.ResultBean bean){
ContentValues values=new ContentValues();
values.put("name",bean.getName());
values.put("summary",bean.getSummary());
values.put("image_url",bean.getImageUrl());
values.put("type",type);
database.insert("movie1",null,values);
}
public void addAll(int type, List<ContentBean.ResultBean> list){
try{
database.beginTransaction();
for (ContentBean.ResultBean movie:list){
add(type,movie);
}
database.setTransactionSuccessful();
}finally {
database.endTransaction();
}
}
public void del(int type){
database.delete("movie1","type=?",new String[]{String.valueOf(type)});
}
public void del(int type,String name){
database.delete("movie1","name=? and type=?",new String[]{name,String.valueOf(type)});
}
public Cursor sel(int type){
Cursor query = database.query("movie1", null, "type=?", new String[]{String.valueOf(type)}, null, null, null);
return query;
}
}
NetUtil
public class NetUtil {
private static NetUtil netUtil;
public NetUtil() {
}
public static NetUtil getIntance(){
if(netUtil==null){
netUtil=new NetUtil();
}
return netUtil;
}
public interface CallBack<T>{
void onsuccess(T t);
}
//是否有可用的网络
public boolean hasNetwork(Context context) {
ConnectivityManager cm =(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isAvailable();
}
//判断是否是手机网络
public boolean isMobileNetwork(Context context) {
ConnectivityManager cm =(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
return activeNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE;
}
@SuppressLint("StaticFieldLeak")
public void requestData(String strurl, final Class clazz, final CallBack callback){
new AsyncTask<String, Void, Object>() {
@Override
protected Object doInBackground(String... strings) {
return requestData(strings[0],clazz);
}
@Override
protected void onPostExecute(Object o) {
callback.onsuccess(o);
}
}.execute(strurl);
}
public <T> T requestData(String str,Class cals){
return (T) new Gson().fromJson(requestData(str),cals);
}
public String requestData(String str){
try {
URL url = new URL(str);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setConnectTimeout(5000);
urlConnection.setReadTimeout(5000);
int responseCode = urlConnection.getResponseCode();
if(responseCode==200){
String s = streamTostring(urlConnection.getInputStream());
return s;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
return null;
}
public String streamTostring(InputStream inputStream) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder builder=new StringBuilder();
for (String tmp=bufferedReader.readLine();tmp!=null;tmp=bufferedReader.readLine()){
builder.append(tmp);
}
return builder.toString();
}
}
BitmapUtil
public class BitmapUtil {
//根据图片路径 指定的宽高 加载缩放图片
public static Bitmap scaleBitmap(String imagePath, int width, int height) {
//第一次只加载 宽高 信息
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imagePath, options);
//根据图片原始宽高 和请求宽高 计算采样率
options.inSampleSize = Math.max(options.outWidth / width, options.outHeight / height);
//设置真正加载图片
options.inJustDecodeBounds = false;
//第二次加载图片
return BitmapFactory.decodeFile(imagePath, options);
}
}
App图片全局设置
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
ImageLoader.getInstance().init(new ImageLoaderConfiguration.Builder(this)
.memoryCacheSizePercentage(10)
.diskCacheSize(50*1024*1024)
.defaultDisplayImageOptions(new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.showImageForEmptyUri(R.mipmap.ic_launcher)
.showImageOnFail(R.mipmap.ic_launcher)
.showImageOnLoading(R.mipmap.ic_launcher)
.bitmapConfig(Bitmap.Config.RGB_565)
.build())
.build());
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout android:layout_width="match_parent"
android:id="@+id/draw"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v4.view.ViewPager
android:id="@+id/p_viewpager"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@+id/tab_bottom"
/>
<android.support.design.widget.TabLayout
android:id="@+id/tab_bottom"
android:layout_width="0dp"
android:orientation="horizontal"
app:tabMode="fixed"
app:tabGravity="fill"
android:layout_alignParentBottom="true"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/p_viewpager"
/>
</android.support.constraint.ConstraintLayout>
<FrameLayout
android:id="@+id/leftfragment"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#fff"
/>
</android.support.v4.widget.DrawerLayout>
left_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ListView
android:id="@+id/listviews"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</android.support.constraint.ConstraintLayout>
two.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.design.widget.TabLayout
android:id="@+id/tab_top"
android:orientation="horizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tabGravity="fill"
app:tabMaxWidth="0dp"
app:tabMode="fixed"
app:layout_constraintBottom_toTopOf="@+id/c_viewpager"
/>
<android.support.v4.view.ViewPager
android:id="@+id/c_viewpager"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@+id/tab_top"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</android.support.constraint.ConstraintLayout>
left_image.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="@+id/image"
android:layout_width="120dp"
android:layout_height="120dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:padding="20dp"
/>
</android.support.constraint.ConstraintLayout>
left_text.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:padding="10dp"
/>
</android.support.constraint.ConstraintLayout>
正在上映和即将上映页面
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.handmark.pulltorefresh.library.PullToRefreshListView
android:id="@+id/pull_to_z"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</android.support.constraint.ConstraintLayout>
正在上映和即将上映子条目页面
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="@+id/image"
android:layout_width="150dp"
android:layout_height="130dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/title"
app:layout_constraintBottom_toBottomOf="parent"
/>
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="@+id/image"
app:layout_constraintBottom_toTopOf="@+id/summary"
/>
<TextView
android:id="@+id/summary"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:maxLines="2"
android:ellipsize="end"
app:layout_constraintLeft_toRightOf="@+id/image"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title"
/>
</android.support.constraint.ConstraintLayout>