diff options
Diffstat (limited to 'java/com/android/dialer/calllog/ui')
7 files changed, 162 insertions, 100 deletions
diff --git a/java/com/android/dialer/calllog/ui/AndroidManifest.xml b/java/com/android/dialer/calllog/ui/AndroidManifest.xml index 228167749..eaf71aba8 100644 --- a/java/com/android/dialer/calllog/ui/AndroidManifest.xml +++ b/java/com/android/dialer/calllog/ui/AndroidManifest.xml @@ -13,4 +13,4 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License --> -<manifest package="com.android.dialer.calllog"/> +<manifest package="com.android.dialer.calllog.ui"/> diff --git a/java/com/android/dialer/calllog/ui/AnnotatedCallLogCursorLoader.java b/java/com/android/dialer/calllog/ui/AnnotatedCallLogCursorLoader.java deleted file mode 100644 index cd8622e80..000000000 --- a/java/com/android/dialer/calllog/ui/AnnotatedCallLogCursorLoader.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.dialer.calllog.ui; - -import android.annotation.TargetApi; -import android.content.Context; -import android.content.CursorLoader; -import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; -import android.os.Build; -import com.android.dialer.calllog.database.AnnotatedCallLog; -import com.android.dialer.calllog.database.AnnotatedCallLog.Columns; - -/** CursorLoader which reads the annotated call log. */ -class AnnotatedCallLogCursorLoader extends CursorLoader { - - AnnotatedCallLogCursorLoader(Context context) { - super(context); - } - - @TargetApi(Build.VERSION_CODES.M) // Uses try-with-resources - @Override - public Cursor loadInBackground() { - try (SQLiteDatabase readableDatabase = AnnotatedCallLog.getReadableDatabase(getContext())) { - return readableDatabase.rawQuery( - "SELECT * FROM " - + AnnotatedCallLog.TABLE_NAME - + " ORDER BY " - + Columns.TIMESTAMP - + " DESC", - null /* selectionArgs */); - } - } -} diff --git a/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java b/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java new file mode 100644 index 000000000..f9ab21cb3 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +package com.android.dialer.calllog.ui; + +import android.database.Cursor; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.ViewGroup; +import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.CoalescedAnnotatedCallLog; + +/** {@link RecyclerView.Adapter} for the new call log fragment. */ +final class NewCallLogAdapter extends RecyclerView.Adapter<NewCallLogViewHolder> { + + private final Cursor cursor; + private final int timestampIndex; + + NewCallLogAdapter(Cursor cursor) { + this.cursor = cursor; + timestampIndex = cursor.getColumnIndexOrThrow(CoalescedAnnotatedCallLog.TIMESTAMP); + } + + @Override + public NewCallLogViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { + return new NewCallLogViewHolder( + LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.new_call_log_entry, viewGroup, false)); + } + + @Override + public void onBindViewHolder(NewCallLogViewHolder viewHolder, int position) { + cursor.moveToPosition(position); + long timestamp = cursor.getLong(timestampIndex); + viewHolder.bind(timestamp); + } + + @Override + public int getItemCount() { + return cursor.getCount(); + } +} diff --git a/java/com/android/dialer/calllog/ui/NewCallLogFragment.java b/java/com/android/dialer/calllog/ui/NewCallLogFragment.java index b8f2b1326..89ed52fd7 100644 --- a/java/com/android/dialer/calllog/ui/NewCallLogFragment.java +++ b/java/com/android/dialer/calllog/ui/NewCallLogFragment.java @@ -17,30 +17,30 @@ package com.android.dialer.calllog.ui; import android.app.Fragment; import android.app.LoaderManager.LoaderCallbacks; -import android.content.Context; +import android.content.CursorLoader; import android.content.Loader; import android.database.Cursor; import android.os.Bundle; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.CursorAdapter; -import android.widget.ListView; -import android.widget.SimpleCursorAdapter; -import android.widget.TextView; import com.android.dialer.calllog.CallLogComponent; import com.android.dialer.calllog.CallLogFramework; import com.android.dialer.calllog.CallLogFramework.CallLogUi; -import com.android.dialer.calllog.database.AnnotatedCallLog.Columns; +import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.CoalescedAnnotatedCallLog; import com.android.dialer.common.LogUtil; -import java.text.SimpleDateFormat; -import java.util.Locale; +import com.android.dialer.common.concurrent.DialerExecutor; +import com.android.dialer.common.concurrent.DialerExecutorComponent; +import com.android.dialer.common.concurrent.DialerExecutorFactory; /** The "new" call log fragment implementation, which is built on top of the annotated call log. */ public final class NewCallLogFragment extends Fragment implements CallLogUi, LoaderCallbacks<Cursor> { - private CursorAdapter cursorAdapter; + private DialerExecutor<Boolean> refreshAnnotatedCallLogTask; + private RecyclerView recyclerView; public NewCallLogFragment() { LogUtil.enterBlock("NewCallLogFragment.NewCallLogFragment"); @@ -52,8 +52,27 @@ public final class NewCallLogFragment extends Fragment LogUtil.enterBlock("NewCallLogFragment.onCreate"); - CallLogFramework callLogFramework = CallLogComponent.get(getContext()).callLogFramework(); + CallLogComponent component = CallLogComponent.get(getContext()); + CallLogFramework callLogFramework = component.callLogFramework(); callLogFramework.attachUi(this); + + DialerExecutorFactory dialerExecutorFactory = + DialerExecutorComponent.get(getContext()).dialerExecutorFactory(); + + refreshAnnotatedCallLogTask = + dialerExecutorFactory + .createUiTaskBuilder( + getFragmentManager(), + "NewCallLogFragment.refreshAnnotatedCallLog", + component.getRefreshAnnotatedCallLogWorker()) + .build(); + } + + @Override + public void onStart() { + super.onStart(); + + LogUtil.enterBlock("NewCallLogFragment.onStart"); } @Override @@ -64,6 +83,9 @@ public final class NewCallLogFragment extends Fragment CallLogFramework callLogFramework = CallLogComponent.get(getContext()).callLogFramework(); callLogFramework.attachUi(this); + + // TODO: Consider doing this when fragment becomes visible. + checkAnnotatedCallLogDirtyAndRefreshIfNecessary(); } @Override @@ -82,57 +104,44 @@ public final class NewCallLogFragment extends Fragment LogUtil.enterBlock("NewCallLogFragment.onCreateView"); View view = inflater.inflate(R.layout.new_call_log_fragment, container, false); - ListView listView = (ListView) view.findViewById(R.id.list); + recyclerView = view.findViewById(R.id.new_call_log_recycler_view); - this.cursorAdapter = - new MyCursorAdapter( - getContext(), - R.layout.new_call_log_entry, - null /* cursor */, - new String[] {Columns.TIMESTAMP, Columns.CONTACT_NAME}, - new int[] {R.id.timestamp, R.id.contact_name}, - 0); - listView.setAdapter(cursorAdapter); - - getLoaderManager().initLoader(0, null, this); + getLoaderManager().restartLoader(0, null, this); return view; } + private void checkAnnotatedCallLogDirtyAndRefreshIfNecessary() { + LogUtil.enterBlock("NewCallLogFragment.checkAnnotatedCallLogDirtyAndRefreshIfNecessary"); + refreshAnnotatedCallLogTask.executeSerial(false /* skipDirtyCheck */); + } + @Override public void invalidateUi() { LogUtil.enterBlock("NewCallLogFragment.invalidateUi"); - // TODO: Implementation. + refreshAnnotatedCallLogTask.executeSerial(true /* skipDirtyCheck */); } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { - // TODO: This is sort of weird, do we need to implement a content provider? - return new AnnotatedCallLogCursorLoader(getContext()); + LogUtil.enterBlock("NewCallLogFragment.onCreateLoader"); + // CoalescedAnnotatedCallLog requires that all params be null. + return new CursorLoader( + getContext(), CoalescedAnnotatedCallLog.CONTENT_URI, null, null, null, null); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor newCursor) { - cursorAdapter.swapCursor(newCursor); + LogUtil.enterBlock("NewCallLogFragment.onLoadFinished"); + + // TODO: Handle empty cursor by showing empty view. + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + recyclerView.setAdapter(new NewCallLogAdapter(newCursor)); } @Override public void onLoaderReset(Loader<Cursor> loader) { - cursorAdapter.swapCursor(null); - } - - private static class MyCursorAdapter extends SimpleCursorAdapter { - - MyCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) { - super(context, layout, c, from, to, flags); - } - - @Override - public void setViewText(TextView view, String text) { - if (view.getId() == R.id.timestamp) { - text = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US).format(Long.valueOf(text)); - } - view.setText(text); - } + LogUtil.enterBlock("NewCallLogFragment.onLoaderReset"); + recyclerView.setAdapter(null); } } diff --git a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java new file mode 100644 index 000000000..4c459e123 --- /dev/null +++ b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +package com.android.dialer.calllog.ui; + +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.TextView; +import java.text.SimpleDateFormat; +import java.util.Locale; + +/** {@link RecyclerView.ViewHolder} for the new call log. */ +final class NewCallLogViewHolder extends RecyclerView.ViewHolder { + + // TODO: Format correctly using current locale. + private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); + + private final TextView contactNameView; + private final TextView timestampView; + + NewCallLogViewHolder(View view) { + super(view); + contactNameView = view.findViewById(R.id.contact_name); + timestampView = view.findViewById(R.id.timestamp); + } + + void bind(long timestamp) { + contactNameView.setText("Contact Name Placeholder"); + timestampView.setText(dateFormat.format(timestamp)); + } +} diff --git a/java/com/android/dialer/calllog/ui/res/layout/new_call_log_entry.xml b/java/com/android/dialer/calllog/ui/res/layout/new_call_log_entry.xml index ee3efd002..99797fab4 100644 --- a/java/com/android/dialer/calllog/ui/res/layout/new_call_log_entry.xml +++ b/java/com/android/dialer/calllog/ui/res/layout/new_call_log_entry.xml @@ -18,16 +18,20 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="horizontal"> + android:layout_height="wrap_content" + android:padding="8dp" + android:orientation="vertical"> <TextView - android:id="@+id/timestamp" + android:id="@+id/contact_name" android:layout_width="wrap_content" - android:layout_height="wrap_content"/> + android:layout_height="wrap_content" + style="@style/PrimaryText"/> <TextView - android:id="@+id/contact_name" + android:id="@+id/timestamp" android:layout_width="wrap_content" - android:layout_height="wrap_content"/> + android:layout_height="wrap_content" + style="@style/SecondaryText"/> + </LinearLayout>
\ No newline at end of file diff --git a/java/com/android/dialer/calllog/ui/res/layout/new_call_log_fragment.xml b/java/com/android/dialer/calllog/ui/res/layout/new_call_log_fragment.xml index 433dbdd0f..e1d8410b6 100644 --- a/java/com/android/dialer/calllog/ui/res/layout/new_call_log_fragment.xml +++ b/java/com/android/dialer/calllog/ui/res/layout/new_call_log_fragment.xml @@ -15,8 +15,9 @@ ~ limitations under the License --> -<ListView +<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/list" + android:id="@+id/new_call_log_recycler_view" android:layout_width="match_parent" - android:layout_height="match_parent"/> + android:layout_height="match_parent" + android:background="@color/background_dialer_light"/> |